Compare commits

...

219 Commits

Author SHA1 Message Date
kamel5 79a95914f0 Version 1.2.18 2022-02-09 13:55:34 +01:00
kamel5 2f64512710 Cosmetic changes 2021-12-22 13:26:56 +01:00
kamel5 d11d09ca6e Merge branch 'pbiering/skindesigner-extend-detection-recording-isHD-isUHD' 2021-12-22 12:22:31 +01:00
Peter Bieringer 9690f6d8a0 remove debug lines 2021-12-20 19:13:00 +01:00
Peter Bieringer 5e5e5c4fbc extend detection of isHD and isUHD in case of stored EPG info (event) is missing any information regarding video (e.g. if EPG is missing on a channel) 2021-12-20 18:42:58 +01:00
kamel5 5b61c36484 Fix compiler error 2021-06-07 11:37:40 +02:00
kamel5 7d269ffd85 Version 1.2.17 2021-05-31 16:05:10 +02:00
kamel5 c6c89529a6 Update Skin estuary4vdr 2021-05-31 15:56:29 +02:00
kamel5 da79cb71b4 Update Skin estuary4vdr to display errors in recording info 2021-05-30 14:15:04 +02:00
kamel5 8aeb848044 Add token errors for recordings (VDR >= 2.5.4) 2021-05-30 14:15:00 +02:00
kamel5 b55994a8a6 Fix display of the background in the display channel
If you enter the display channel in Zapcockpit mode with the right or
left button and exit with OK, the background of the display channel was
not displayed.
2021-05-30 11:42:02 +02:00
kamel5 b47f544ad5 Fix incorrect display of posters and banners in the recording menu
When using the narrow recording menu, the posters and banners were
displayed incorrectly
2021-05-29 15:51:27 +02:00
kamel5 4a89d28f03 Fix display of events in channel display
When switching to a channel without EPG, the display of the current and
following program was not updated.
2021-05-27 11:53:17 +02:00
kamel5 7c47c8e225 Version 1.2.16 2021-05-21 12:10:40 +02:00
kamel5 ebd99e119c Fix update timer in the main menu
The timers in the open main menu were not updated when a timer recording
was started or stopped
2021-05-21 11:46:20 +02:00
kamel5 3c7e014dcc Fix a device is currently recording
The token indicating whether a device is currently recording was not
updated correctly
2021-05-21 11:46:16 +02:00
kamel5 b977e3582a Fix display of recording sign in display channel
The display of the instant timer has been corrected in the display
channel so that all events contained in the timer that have a tmFull
or tmPartial flag are marked with the recording symbol.
2021-05-21 11:46:11 +02:00
kamel5 9b63e8327f Fix Fehler: Aufruf des überladenen »min(int&, int&)« ist nicht eindeutig 2021-05-15 14:57:16 +02:00
kamel5 a7fc762b3d Update timerliste in main menu
The display of the instant timers has been corrected in the main menu so
that they are displayed as in the timer list.
2021-05-10 15:48:52 +02:00
kamel5 596c86c780 Merge branch 'pbiering/vdrstatus-displaymenu' 2021-05-06 10:55:25 +02:00
kamel5 d6f5e6808b Delete asterisk 2021-05-06 10:54:12 +02:00
Peter Bieringer 0259d38d2f fix/update changelog 2021-05-05 19:56:26 +02:00
Peter Bieringer 0b2666f62d remove comment 2021-05-05 18:51:01 +02:00
Peter Bieringer d4b1765aaf fix vdrstatus in displaymenu 2021-05-05 18:03:13 +02:00
Peter Bieringer 3aae0169b4 expose vdrstatus to displaymenu 2021-05-05 17:39:40 +02:00
kamel5 0159d536d0 Merge branch 'pbiering/vdrHasTimers' 2021-05-05 11:33:10 +02:00
kamel5 ccba1c23fd Revert "update version"
This reverts commit fce870a315.
2021-05-05 11:32:00 +02:00
kamel5 6583c93a6f Revert "update version token"
This reverts commit 64658a1f56.
2021-05-05 11:31:37 +02:00
Peter Bieringer 2d7a9ab3a3 Merge branch 'vdrHasTimers' of gitlab.com:pbiering/skindesigner into vdrHasTimers 2021-05-04 19:22:45 +02:00
Peter Bieringer 4daec64480 add {vdrHasTimers} to vdrstatus - can be used in skins for e.g. REC/SCHED/FREE (in combination with {vdrIsRecording}) 2021-05-04 19:20:29 +02:00
Peter Bieringer 64658a1f56 update version token 2021-05-04 19:19:30 +02:00
Peter Bieringer fce870a315 update version 2021-05-04 19:19:30 +02:00
kamel5 09925e6113 Fix Incorrect detection of a recording that is currently running
To set timeShiftActive correctly, it is not sufficient to compare the
name of the recording and the timer in cGlobalTimers::IsRecording()
if no short text is available. Therefore, the start time of both is now
also compared.
2021-05-04 14:38:52 +02:00
kamel5 4b2861e030 Merge branch 'pbiering/recIsInUse-vdrIsRecording' 2021-05-04 13:58:03 +02:00
Peter Bieringer 39c1062353 add {vdrHasTimers} to vdrstatus - can be used in skins for e.g. REC/SCHED/FREE (in combination with {vdrIsRecording}) 2021-05-04 07:33:08 +02:00
Peter Bieringer 589749731f update version token 2021-05-03 10:59:08 +02:00
Peter Bieringer 1c9fd38cc7 update version 2021-05-03 10:58:55 +02:00
Peter Bieringer 0ca96e8b3a add additional vdrstatus exposing "vdrIsRecordingsHandlersActive" and "vdrIsRecording" - can be used in skins for e.g. IDLE/BUSY REC/FREE 2021-05-03 10:53:55 +02:00
Peter Bieringer 700798ba21 add additional recording flag "isInUse" - can be used in skins for e.g. records in cutting/copy(queue) 2021-05-03 07:01:04 +02:00
kamel5 0aeb15d03a Merge branch 'pbiering/code-optimization' into develop 2021-04-25 11:14:40 +02:00
kamel5 22b24eb455 Update skin estuary4vdr displaychannel.xml
Fix incorrect display of weather info in Displaychannel.
2021-04-08 17:02:44 +02:00
kamel5 f5a29826cb Update skin estuary4vdr displaymenudefault.xml
Fix incorrect display of list entrys separated by tab in Displaymenu.
2021-04-08 17:02:34 +02:00
kamel5 50879fa931 Fix segfault with mpv plugin (thx to @lnj at vdr-portal.de)
This fix prevents a segfault when using the mpv plugin because there are
no cutmarks.
2021-03-28 12:26:24 +02:00
kamel5 894b5865cd Merge branch 'pbiering/fix-rsvg' 2021-03-23 15:57:20 +01:00
Peter Bieringer fda2a4ec74 fix issue introduced with 85df1e7f980f0f7092523e5ac9ed4ff6db51d82e: (process:24445): librsvg-CRITICAL **: 16:03:34.427: rsvg_handle_read_stream_sync: assertion 'is_input_stream(stream)' failed 2021-03-20 16:37:56 +01:00
Peter Bieringer 4821574437 remove of duplicate code by introducing macros by https://gitlab.com/Mike838 from https://gitlab.com/kamel5/skindesigner/-/issues/1#note_508426185 2021-03-20 16:06:45 +01:00
kamel5 dc617b52fa Version 1.2.15 2021-03-15 14:15:07 +01:00
kamel5 cef6ca78a2 Fix cutting marks wasn't updated 2021-03-15 14:10:18 +01:00
kamel5 85df1e7f98 Eliminate warnings 2021-03-11 13:21:45 +01:00
kamel5 3334263a96 Merge branch 'pbiering/skindesigner-fix-tuner-device-mapping' 2021-03-11 12:52:48 +01:00
Peter Bieringer 4d3fa0bc71 fix tuner device mapping in case tuners are not starting as first device (e.g. NetCeiver mcli) 2021-03-11 12:52:08 +01:00
Peter Bieringer cbce894c0c Merge remote-tracking branch 'upstream/master' 2021-03-11 08:16:55 +01:00
kamel5 9a0eac1c4f Update italian tanslation in metrixhd (thx to @fiveten_59 at vdr-portal.de) 2021-03-07 19:27:18 +01:00
kamel5 5f7337b50c Update italian tanslation in estuary4vdr (thx to @fiveten_59 at vdr-portal.de) 2021-03-07 14:45:49 +01:00
kamel5 e3becb6c61 Version 1.2.14 2021-03-04 17:47:41 +01:00
kamel5 fdc8195174 Add active recordings to timeshift mode
If the current program is paused (timeshift mode), a recording
is created with an "@" at the beginning. A skin can display
this mode differently than the normal playback of a recording.
This change also enables a different display mode for currently
active timer recordings.
2021-03-04 17:47:32 +01:00
kamel5 e7ea88c253 Revert "Disabled timeshift display for non timeshift recordings"
This reverts commit 1fc5379e2e.
2021-03-04 17:33:59 +01:00
kamel5 80cb1ec0ef Update estuary4vdr
Correct position of time
2021-03-04 17:33:41 +01:00
Peter Bieringer 105fe893a2 Merge remote-tracking branch 'upstream/master' 2021-03-01 07:25:50 +01:00
kamel5 402044d4c4 Version 1.2.13 2021-02-15 14:00:40 +01:00
kamel5 99d2bc6a86 Eliminate SetRecordingLength 2021-02-15 14:00:40 +01:00
kamel5 15aa722410 Move SetTimeShiftValues 2021-02-15 14:00:40 +01:00
kamel5 afa9cb77a3 Add element timeShiftTimes to displayreplay
In displayreplay the tokens recstart, playbacktime and timeshiftrest
added to display start time, actual playback time and the rest of
the actual recording in timeshiftmode.
2021-02-15 14:00:35 +01:00
kamel5 1fc5379e2e Disabled timeshift display for non timeshift recordings 2021-02-15 12:22:33 +01:00
kamel5 7a70ed13a7 Add tokens eventstart and eventstop to eDRRecTitleST
Tokens eventstart and eventstop can be used in displayreplay timshiftmode to
display the start and end time of the coresponding event
2021-02-15 12:22:33 +01:00
kamel5 808fba2367 Add datetime to displaychannel in skin estuary4vdr 2021-02-15 10:50:35 +01:00
kamel5 64599db339 In timeshift mode, the title of the actual playback position is displayed
If the timeshift mode is activated during playback, the title of the
program that was active when the time shift started is displayed by
pressing OK.
The behavior has now been changed so that the title of the program is
displayed in the actual playback position when you press OK.
2021-02-11 17:39:18 +01:00
kamel5 628a28201b Revision cViewReplay::SetTimeShiftValues()
When the timeshift recording reaches the end time of the start event,
the progress bar and the end time no longer shows any useful
information.
From this version the current live event is used to calculate the
progress bar and the end time.
2021-02-11 17:34:23 +01:00
kamel5 538d59ca4e An error with the remaining time in the channel display has been fixed
The remaining time in the channel display wasn't updated.
A new token "currentremaining" was introduced in the Progressbar section
of displaychannel.xml.
2021-02-11 17:34:23 +01:00
kamel5 78d424d256 Token eLeMenuDefaultIT::devstatus added 2021-02-09 15:57:13 +01:00
kamel5 cba8fe1eb4 Missing token eCeMenuSchedulesIT::durationminutes added 2021-02-09 15:57:13 +01:00
kamel5 b9093a6dca Update Skin estuary4vdr 2021-02-09 15:57:10 +01:00
kamel5 c3f7a2cfdf Fixed a bug in timeshift mode that prevented the progress bar from updating in pause mode 2021-02-08 15:31:59 +01:00
kamel5 6972a59e1b A bug with timeshift in connection with global timers has been fixed
With commit 8a04a17 an error was introduced which did not take the global
timers into account in the timeshift replay.
thanks to @machtnix at vdr-portal.de for finding the bug
2021-02-08 11:05:51 +01:00
kamel5 f8b6b2cf1b This reverts bd86dd4de "disabled timeshift display for instant recordings" 2021-02-06 17:58:19 +01:00
kamel5 0eaed1eb91 Version 1.2.12 2021-02-06 13:55:19 +01:00
kamel5 a48427cffc Merge branch 'pbiering/skindesigner-fix-eDmDetailedHeaderRec-crash' 2021-02-06 13:42:17 +01:00
Peter Bieringer 764f657620 Merge branch 'fix-Wstringop-overflow' 2021-02-06 12:55:42 +01:00
Peter Bieringer dd30dacb5b fix crash caused by cVeDmDetailheaderRec::Parse introduced in 1.2.10 2021-02-06 12:52:19 +01:00
Peter Bieringer 4bebeda1b0 fix 3x Wstringop-overflow compiler warnings 2021-02-06 09:36:17 +01:00
Peter Bieringer 7d63e95471 add TODO token 2021-02-06 08:12:45 +01:00
kamel5 78483aa3d8 Merge branch 'pbiering/skindesigner-add-Recording-isInUse' 2021-02-05 12:51:32 +01:00
Peter Bieringer 9def7d2b0d rename to isRecording, filter IsInUse proper, add also to replay recinfo 2021-02-05 08:44:00 +01:00
Peter Bieringer ca354a29e6 added token for recordings: isInUse 2021-02-05 08:06:22 +01:00
kamel5 452a4384c2 Version 1.2.11 2021-02-03 13:58:09 +01:00
kamel5 1c393e23a5 Fixed an error in displayreplay if no recording information are available 2021-02-03 13:53:25 +01:00
kamel5 6aeaf41467 Merge branch 'pbiering/skindesigner-fix-busy-svdrpresult' 2021-02-03 11:58:00 +01:00
Peter Bieringer b044321b1f also be initialized in case of backup skin is active 2021-02-03 07:13:41 +01:00
Peter Bieringer 68d4d6acae SVDRP: do not reload in case plugin is not fully initialized (results in VDR crash)
SVDRP: respond with proper error message in case of OSD is active or parsing error
2021-02-03 07:10:24 +01:00
Peter Bieringer 5e269ecaaa mark deprecated functions 2021-02-02 22:12:35 +01:00
Peter Bieringer ea963c73eb Merge remote-tracking branch 'upstream/master' 2021-01-28 21:05:12 +01:00
Peter Bieringer 83c85870fb align tuner number (starting internally with 0) with VDR numbering (starting with 1) 2021-01-28 13:27:09 +01:00
Peter Bieringer 6751c4cd4e Merge branch 'master' of gitlab.com:kamel5/skindesigner 2021-01-27 20:41:27 +01:00
kamel5 4500b62b5c Version 1.2.10 2021-01-25 16:05:35 +01:00
kamel5 f711a71722 Update skins/estuary4vdr/xmlfiles/displaymenudetailrecording.xml 2021-01-25 15:59:44 +01:00
kamel5 1315e73217 Update skins/estuary4vdr/xmlfiles/plug-tvguideng-recmenu.xml 2021-01-25 15:59:34 +01:00
kamel5 858143ce2b Update skins/estuary4vdr/xmlfiles/plug-tvguideng-root.xml 2021-01-25 15:59:22 +01:00
kamel5 3255936658 Merge branch 'pbiering/skindesigner-add-menurecording-recchannel-and-add-fallback' 2021-01-24 13:06:13 +01:00
Peter Bieringer 1aead6d400 update version, extend history 2021-01-24 13:05:16 +01:00
kamel5 c9c2d953a5 - retrieve ChannelName from 'info' and fallback via ChannelID from active channel list (reverse mechanism)
- remove exposing ChannelID (senseless as default 'info' is not containing it)
2021-01-24 13:02:35 +01:00
Peter Bieringer 646fcad7d5 - retrieve ChannelName from 'info' and fallback via ChannelID from active channel list (reverse mechanism)
- remove exposing ChannelID (senseless as default 'info' is not containing it)
2021-01-24 12:11:23 +01:00
Peter Bieringer 91d06d15a2 update version, extend history 2021-01-24 09:46:47 +01:00
Peter Bieringer b9b82875ba expose to displaymenurecordings: recchannelname, recchannelid, recchannelnumber
add fallback to get name/id from 'info' in case channel is no longer in active channel list
2021-01-23 23:19:16 +01:00
Karl Melscher 16eb7e8e53 Merge branch 'detect-isRadio-workaround' into 'master'
detect isRadio proper in case recording is missing "X 1" (happen on e.g. RTL channel)

See merge request kamel5/skindesigner!7
2021-01-23 10:17:45 +00:00
Peter Bieringer 2eef09e6aa detect isRadio proper in case recording is missing "X 1" (happen on e.g. RTL channel) 2021-01-23 10:32:08 +01:00
kamel5 59248ccebb Merge branch 'pbiering/skindesigner-add-isRadio-to-recording' 2021-01-22 19:44:15 +01:00
Peter Bieringer efeb8d69c4 update history 2021-01-22 18:03:02 +01:00
Peter Bieringer f127c8d948 add-isRadio-to-recording 2021-01-22 18:01:23 +01:00
kamel5 c0dad5a14f Merge branch 'pbiering/skindesigner-expose-isHD-isUHD-to-channel' 2021-01-22 10:43:59 +01:00
Peter Bieringer fdc1a7357e add isHD and isUHD to channel list 2021-01-21 20:05:18 +01:00
kamel5 bcc24977b0 Merge branch 'pbiering/skindesigner-add-isRadio-to-channel' 2021-01-21 11:57:02 +01:00
kamel5 a4d51d31de Merge branch 'pbiering/skindesigner-add-isUHD-to-screenresolution' 2021-01-21 11:56:01 +01:00
kamel5 ddf861d6f6 Merge branch 'pbiering/skindesigner-expose-recording-isUHD' 2021-01-21 11:55:05 +01:00
kamel5 7a6858b8f3 Merge branch 'pbiering/skindesigner-expose-recording-isHD' 2021-01-21 11:53:29 +01:00
Peter Bieringer f3f4ee2d48 expose isRadio to menuchannel 2021-01-21 08:59:43 +01:00
Peter Bieringer 66f090afdb add isUHD to screenresolution
change mechanism to detect video type using screen height instead of guessing height from width
2021-01-21 07:49:35 +01:00
Peter Bieringer 4c4b9f7837 expose on top of isHD now also isUHD for recordings 2021-01-20 21:37:36 +01:00
Peter Bieringer ce520980fd fix detection order from high to low 2021-01-20 21:29:37 +01:00
kamel5 5dbfd52784 Version 1.2.9 2021-01-17 14:36:20 +01:00
kamel5 4c4374ecb2 improve HD detection code, catch also stream content 9 (Submitted by Peter Bieringer) 2021-01-17 14:27:34 +01:00
kamel5 c5f0b5d3f8 added tokens for framesPerSecond and isHD (Submitted by Peter Bieringer) 2021-01-17 14:27:02 +01:00
kamel5 bc9cb23ed7 Refresh imgCache if OsdProvider was changed (Thanks to lnj @vdr-portal.de) 2020-12-11 18:49:26 +01:00
kamel5 df8c8e2993 Revert "Refresh imgCache if OsdProvider was changed (simple fix)"
This reverts commit 3fbc601315.
2020-12-11 17:43:16 +01:00
kamel5 3fbc601315 Refresh imgCache if OsdProvider was changed (simple fix) 2020-09-23 14:26:13 +02:00
kamel5 8c9a0d7925 Version number greater than 3 digits possible 2020-07-27 10:29:30 +02:00
kamel5 eeb5bfefb2 Update services/epgtimer.h 2020-07-15 13:21:38 +02:00
kamel5 029ac7e9e4 Install libskindesignerapi after all other 2020-07-15 13:21:38 +02:00
kamel5 8ebb3610da Updated xml files 2020-07-15 13:21:38 +02:00
kamel5 5402edd41b Update Locking in extensions/globaltimers.c 2020-07-15 13:21:38 +02:00
kamel5 6f14ddae8a Refactor reruns 2020-07-15 13:21:33 +02:00
kamel5 f156e44599 Eliminate a lock sequence report in vdr-2.4.0_zapcockpit.patch 2020-02-10 11:32:36 +01:00
kamel5 66351a48f9 Optimization for softhdcuvid 2019-10-12 18:28:07 +02:00
kamel5 a685cbb131 Version 1.2.8 2019-06-21 14:10:45 +02:00
kamel5 751e903301 Add vdr-2.4.0_zapcockpit.patch 2019-06-21 14:09:35 +02:00
kamel5 8a04a17fc0 Eliminate a look sequence report in displayreplay 2019-06-21 14:07:00 +02:00
kamel5 9278f18cb9 Eliminate a look sequence report in displaychannel 2019-06-21 14:02:15 +02:00
horchi 5b03953fd1 anged menu numbering handling vor mcMain 2018-03-03 09:03:00 +01:00
horchi 9647640dc7 extended epg2vdr timer interface for schedules 2018-02-17 15:34:44 +01:00
horchi e068cb93fd added timer type to epg2vdr interface 2018-02-16 19:55:36 +01:00
horchi beeb82bbda compatibility to vdr 2.3.8 2018-02-16 18:12:48 +01:00
louis c8d54dbe25 Version 1.2.3 2016-10-03 15:49:57 +02:00
louis f6c11ce9ea fixed animns in zapcockpit 2016-10-03 15:48:09 +02:00
louis 2378bc8c4e fixed slow ff and rew 2016-10-03 15:20:36 +02:00
louis 0ef5487e6f fixed memory leak 2016-09-25 12:01:41 +02:00
louis e75aaa6f33 only create animator if not existing 2016-09-25 11:11:32 +02:00
louis 74f7250c74 Version 1.2.2 2016-09-24 15:20:31 +02:00
louis e114338c4e added tokens for slow forward and rewind in displayreplay 2016-09-24 15:19:03 +02:00
louis d9ab1eb1ca fixed crash for timers without channel 2016-09-24 14:29:56 +02:00
louis cc1efd1d2e fixed crash when replacing recording menu with extrecmenu 2016-09-24 14:25:58 +02:00
louis ead8056990 Version 1.2.1 2016-07-31 07:19:59 +02:00
louis 49fbf2c00e cleanup 2016-07-31 07:19:05 +02:00
louis 6b77310d70 fixed small bug in metrixhd 2016-07-30 18:24:44 +02:00
louis a2f9e616ee fixed shiftout of viewelements which were not drawn at shiftin 2016-07-30 18:22:57 +02:00
louis 88982c3230 cleanups 2016-07-30 17:31:34 +02:00
louis 6acc22e5c2 fixed bug that listelements were not drawn after scrolling 2016-07-30 15:05:47 +02:00
louis dddb273526 fixed crash using too small list shifttimes 2016-07-30 09:07:34 +02:00
louis b8d055f568 added (optional) poster thumbs in recording menu 2016-07-25 18:56:51 +02:00
louis 0ea566bacd fixed build error 2016-07-23 17:42:10 +02:00
louis 404b9f3add Version 1.2.0 2016-07-23 14:17:03 +02:00
louis 8c28b0c0fb adapted estuary4vdr 2016-07-23 14:08:37 +02:00
louis e3525032e8 updated metrixhd 2016-07-23 09:34:32 +02:00
louis 0534a8ae06 added some plugin icons fur estuary4vdr 2016-07-22 15:45:32 +02:00
louis 54c385ca11 added noteq compare type for conditions 2016-07-22 15:36:25 +02:00
louis a79af20c34 redesigned animations 2016-07-22 15:21:09 +02:00
louis 4f3c24df7b corrected audio_active curtom icon 2016-06-26 13:20:11 +02:00
louis 4098ceddbf version 1.1.5 2016-06-25 06:36:32 +02:00
louis c4c4a10909 updated metrixhd thx@saman 2016-06-25 06:35:48 +02:00
louis 3391710b8d added some icons for estuary4vdr 2016-06-25 06:31:16 +02:00
louis 3b3046bc33 fixed bug displaying signalquality 2016-06-25 05:49:06 +02:00
louis 3572c27dc9 fixed scrolling with centered aligned text 2016-06-25 05:43:48 +02:00
louis 3b2944496a Version 1.1.4 2016-06-19 06:42:47 +02:00
louis 0e04d4eaea update metrixhd - thx@saman 2016-06-19 06:39:50 +02:00
louis f3a27ba22d updating skinrepo only when opening skindesigner setup the first time 2016-06-18 13:45:00 +02:00
louis 0460690ec8 added valign bottom for vertical loops 2016-06-18 13:09:26 +02:00
louis 97a9c7e40f Version 1.1.3 2016-06-12 11:03:21 +02:00
louis a9cbdf00fe timeshift detection for remote timers 2016-06-12 11:02:28 +02:00
louis 49823486f6 added wide schedules menu in estuary4vdr 2016-06-11 06:27:58 +02:00
louis 754e462bc5 added channel background color for different estuary4vdr themes 2016-05-30 18:12:50 +02:00
louis 81fbdacf68 Version 1.1.2 2016-05-30 05:30:01 +02:00
louis 79623b6571 fixed missing check for zapcockpit patch 2016-05-30 05:29:15 +02:00
louis 7b26d65360 updated italian translation 2016-05-29 16:49:29 +02:00
louis d8a0c880d5 Version 1.1.1 2016-05-29 10:41:45 +02:00
louis 5d927af79c updated zapcockpit patch 2016-05-29 10:38:18 +02:00
louis 87f3d895f7 left / right keys in zappilot configurable in skin 2016-05-29 10:07:28 +02:00
louis 75668612be fixed alignment of lists 2016-05-28 13:21:32 +02:00
louis 2b1d941f39 removed scrolling of current element in setup menus in estuary4vdr 2016-05-28 09:43:46 +02:00
louis 020984c5f3 updated finish translation 2016-05-28 09:13:43 +02:00
louis 9611f9b011 added fading and shifting for displaytracks 2016-05-27 17:51:11 +02:00
louis e3a1577c7c fixed typo in estuary4vdr 2016-05-27 16:50:39 +02:00
louis 97d2d5795c added estuary4vdr hungarian translation 2016-05-27 13:11:35 +02:00
louis ed8273883e fixed ending of animations 2016-05-27 12:13:39 +02:00
louis aa8370363a added finish translation 2016-05-27 09:56:23 +02:00
louis 67ce4befdf Version 1.1.0 2016-05-26 13:59:27 +02:00
louis e2f7852589 cosmetics 2016-05-26 13:58:33 +02:00
louis a57c44b068 introduced zapcockpit extension 2016-05-26 10:47:45 +02:00
louis ffb414cdee Version 1.0.3 2016-05-14 10:08:13 +02:00
louis b41d0f2431 fixed display of last recordings in main menu 2016-05-14 10:07:07 +02:00
louis f3db608253 added fritzbox icon 2016-05-14 07:15:46 +02:00
louis 01945e83fc fixed loading of timers in displaychannel 2016-05-11 17:37:32 +02:00
louis 32b78b2f57 fixed timer recording detection in main menu 2016-05-06 09:03:31 +02:00
louis 8e98ebcd6b fixed detection of recording timers 2016-05-06 08:05:04 +02:00
louis 7994fc200a implemented epg2vdr support 2016-05-04 16:21:42 +02:00
louis 24cf03d3f8 Version 1.0.2 2016-05-01 06:37:55 +02:00
louis 5b2401caf1 optimized flushes when more animations are running in parallel 2016-05-01 06:35:13 +02:00
louis f45af8f826 fixed bugwith empty loop functions 2016-05-01 06:22:52 +02:00
louis 8d4a1b12b3 improved vdrstats.default script 2016-04-30 18:01:27 +02:00
louis b528d69dd4 Version 1.0.1 2016-04-30 06:50:35 +02:00
louis f4f64e96e5 improved estuary4vdr 2016-04-30 06:49:30 +02:00
louis 4076377e21 fixed check if menuicon exists 2016-04-19 16:54:30 +02:00
louis dd25359150 Version 1.0.0 2016-04-17 09:30:31 +02:00
louis 831b055b2b added new default skin estuary4vdr 2016-04-17 09:29:54 +02:00
louis 6004cf72fc fixed reading of skins for xfs filesystems again 2016-04-16 11:34:00 +02:00
louis 5589e956e0 Version 0.9.6 2016-04-16 10:19:16 +02:00
louis 5f060dd594 fixed reading of skins for xfs filesystems 2016-04-16 10:15:24 +02:00
louis 0e93a8663f improved disabling of skininstaller 2016-04-16 10:01:29 +02:00
louis 92553a8134 fixed hiding of viewelemments when shifting 2016-04-16 09:18:51 +02:00
louis aec88498ff fixed scrolling in displaychannel channelinfo 2016-04-15 13:55:13 +02:00
louis 7111ae36a8 fixed bug that viewelement does not stop scrolling when cleared 2016-04-12 16:41:49 +02:00
louis fe1016fed6 enlarged svgtemplates for menuicons and skinparts 2016-04-12 16:26:42 +02:00
802 changed files with 49278 additions and 4612 deletions

128
HISTORY
View File

@ -67,9 +67,9 @@ Version 0.0.3
- fixed Bug that displaychannel was not shown after closing displaymenu with
"backspace" (with active menuorg plugin)
- fixed Bug with menuselection Patch
- added tokens {month}, {monthname} and {year} in displaymenutimers listitem and
- added tokens {month}, {monthname} and {year} in displaymenutimers listitem and
currentitem
- added dedicated tokens for posters and banners in <srapercontent> in
- added dedicated tokens for posters and banners in <srapercontent> in
displaychannel and displayreplay
- added Plugin Interface
- fixed crash when clearing a message in displaychannel and displayreplay
@ -81,7 +81,7 @@ Version 0.0.4
Version 0.0.5
- added {channelnumber} and {channelname} Tokens in displaymenudetailepg
- added {channelnumber} and {channelname} Tokens in displaymenudetailepg
detailheader
- fixed {hasicon} Token in displaymenu header
- added {newmails} Token in displaychannel statusinfo, mailbox plugin
@ -111,7 +111,7 @@ Version 0.0.8
Version 0.1.0
- fixed display of color buttons in detailed views
- fixed possible Nullpointer access in displaymenurootview
- fixed possible Nullpointer access in displaymenurootview
- added currentschedule viewelement in displaymenumain
- fixed bug that wrong channel was shown in header of whatson
if entering from whatsonnow
@ -180,7 +180,7 @@ Version 0.1.6
adds its vakues and potentially overrides valués from globals.xml
- check icons, menuicons and skinparts additionally directly in skin folder
to allow default images which can be used for all skins
- fixed bug that setup variables are sometimes not identified in case two
- fixed bug that setup variables are sometimes not identified in case two
or more skin names start identically
Version 0.2.0
@ -195,7 +195,7 @@ Version 0.2.1
- some more nopacity optimizations - thanx@utility
- added possibiliy to use submenus in the skin setup menus
- reloading active skin directly after closing setup menu so that
changes of setup parameters are immediately in use
changes of setup parameters are immediately in use
Version 0.2.2
@ -260,7 +260,7 @@ Version 0.3.3
no signal information will be fetched to improve performance.
Version 0.3.4
- fixed backward compatibility to VDR version < 2.1.1 where
cRecording::IsInUse() was introduced
- automatically detect type of image if no file extension is available
@ -270,7 +270,7 @@ Version 0.4.0
- fixed bug that time was not correctly drawn if a submenu implements
its own time display
- fixed bug that date was drawn every flush in displayreplay
- fixed bug that date was drawn every flush in displayreplay
- fixed bug in metrixhd timers menu
- fixed bug that datetime was not correctly drawn if a submenu implements
its own datetime display
@ -290,7 +290,7 @@ Version 0.4.2
- fixed bug that string tokens are not evaluated in area conditions
- added possibility to draw a debug grid in views
- added more info if debugImage is activted in config
- added possibility for blinking images, texts, rectangles, ellipses
- added possibility for blinking images, texts, rectangles, ellipses
and slopes
- adapted libskindesignerapi makefile for LCLBLD
@ -376,7 +376,7 @@ Version 0.5.3
- added SVG Template parsing
- fixed memory leak when creating fonts
- fixed crash using animated images in plugins
- added banner to displaymenuschedulescurrentview and
- added banner to displaymenuschedulescurrentview and
displaymenureplaycurrentview
- immplemented areacontainers to group areas
- fixed bug displaying pixmaps with transparency
@ -406,10 +406,10 @@ Version 0.6.2
Version 0.6.3
- implemented horizontal menus
For displaying horizontal menus with VDR <= 2.2.x a VDR
patch is required (see /patches/vdr-2.2.0_horizontal_menu.patch
in the plugin source directory). Without this patch the keys
left/right and up/down are not toggled in horizontal menus.
For displaying horizontal menus with VDR <= 2.2.x a VDR
patch is required (see /patches/vdr-2.2.0_horizontal_menu.patch
in the plugin source directory). Without this patch the keys
left/right and up/down are not toggled in horizontal menus.
With VDR >= 2.3.1 this patch is not needed anymore.
- added possibility to add conditions to <menuitems> elements
- added possibility to define a viewelement several times with
@ -418,7 +418,7 @@ Version 0.6.3
- added "valign" option in <drawtextbox>. If the box height is set
and the text does not need the complete height, with valign="center"
the text can be placed horizontally centered inside the box borders.
- implemented optional horizontal main-, recordings- and
- implemented optional horizontal main-, recordings- and
weatherforecast menu in metrixhd
Version 0.7.0
@ -431,3 +431,101 @@ Version 0.7.1
- added possibility to define help texts for skin setup parameters
Version 0.7.2
Version 1.2.4 (horchi)
- added compatibility to vdr 2.3.8
Version 1.2.5 (horchi)
- added timer type to epg2vdr interface
Version 1.2.6 (horchi)
- extended epg2vdr timer interface for schedules
Version 1.2.7 (horchi)
- changed menu numbering handling vor mcMain
> now only numbers up to 999 are detected as 'Numbering'
Version 1.2.8 (kamel5)
- fixed some look sequence reports
- Updated Makefile
- Optimization for softhdcuvid
- Refactor reruns
- Update services/epgtimer.h
- Refresh imgCache if OsdProvider was changed
Version 1.2.9
- [pbiering] added tokens for framesPerSecond and isHD
- [pbiering] improve HD detection code, catch also stream content 9
Version 1.2.10 (buggy)
- [pbiering] added tokens for recordings: isUHD, isRadio
- [pbiering] added token for channels: isUHD
- [pbiering] expose to displaymenurecordings: recchannelname, recchannelid
- [pbiering] retrieve ChannelName from 'info' and fallback via ChannelID from active channel list
- [kamel5] Update skin estuary4vdr
Version 1.2.11 (buggy)
- [pbiering] align displayed tuner number (0,1,2 -> 1,2,3)
- [pbiering] SVDRP: do not reload in case plugin is not fully initialized (results in VDR crash)
- [pbiering] SVDRP: respond with proper error message in case of OSD is active or parsing error
- [kamel5] Fixed an error in displayreplay if no recording information are available
Version 1.2.12
- [pbiering] added token for recordings: isRecording
- [pbiering] fix crash caused by cVeDmDetailheaderRec::Parse introduced in 1.2.10
Version 1.2.13
- [kamel5] A bug with timeshift in connection with global timers has been fixed
- [kamel5] Fixed a bug in timeshift mode that prevented the progress bar from updating in pause mode
- [kamel5] Update Skin estuary4vdr
- Token eCeMenuSchedulesIT::durationminutes added
- Token eLeMenuDefaultIT::devstatus added
- [kamel5] An error with the remaining time in the channel display has been fixed
- [kamel5] Revision cViewReplay::SetTimeShiftValues
- [kamel5] In timeshift mode, the title of the actual playback position is displayed
- [kamel5] Add token recstart to displayreplay
- [kamel5] Add tokens eventstart and eventstop to eDRRecTitleST
- [kamel5] Disabled timeshift display for non timeshift recordings
- [kamel5] Add element timeShiftTimes with tokens recstart, playbacktime and timeshiftrest to displayreplay
Version 1.2.14
- [kamel5] Revert "Disabled timeshift display for non timeshift recordings"
- [kamel5] Add a different display mode to timeshift for currently active timer recordings
Version 1.2.15
- [kamel5] Update Update italian tanslation in metrixhd and estuary4vdr
- [pbiering] fix tuner device mapping in case tuners are not starting as first device
- [kamel5] Fix cutting marks wasn't updated
Version 1.2.16
- [pbiering] add additional recording flag {isInUse} - can be used in skins for e.g. records in cutting/copy(queue)
- [pbiering] add additional <vdrstatus> exposing {vdrIsRecordingsHandlersActive} and {vdrIsRecording} - can be used in skins for e.g. IDLE/BUSY REC/FREE
- [kamel5] Fix Incorrect detection of a recording that is currently running
- [kamel5] Fix segfault with mpv plugin (thx to @lnj at vdr-portal.de)
- [kamel5] Update skin estuary4vdr
- [pbiering] add {vdrHasTimers} to <vdrstatus> - can be used in skins for e.g. REC/SCHED/FREE (in combination with {vdrIsRecording})
- [pbiering] add <vdrstatus> also to displaymenu.xml to be able to display in header
- [kamel5] Fix display of recording sign in display channel
- [kamel5] Fix a device is currently recording
- [kamel5] Fix update timer in the main menu
Version 1.2.17
- [kamel5] Fix display of events in channel display
- [kamel5] Fix incorrect display of posters and banners in the recording menu
- [kamel5] Fix display of the background in the display channel
- [kamel5] Add token errors for recordings (VDR >= 2.5.4)
- [kamel5] Update Skin estuary4vdr to display errors in recording info
- [kamel5] Update Skin estuary4vdr
Version 1.2.18
- [pbiering] extend detection of isHD and isUHD in case of stored EPG info (event) is missing any information regarding video (e.g. if EPG is missing on a channel)
- [kamel5] Fix compiler error

View File

@ -4,8 +4,8 @@
# $Id$ Makefile 1.0 2014/07/24 louis Exp $
# Config
CONFIG := #-DDOPROFILE # enable profiling code
CONFIG += -DUSE_SKININSTALLER # use skin installer in skindesigner setup
CONFIG := #-DDOPROFILE # enable profiling code
CONFIG += #-DDO_NOT_USE_SKININSTALLER # disable installer in skindesigner setup
# The official name of this plugin.
PLUGIN = skindesigner
@ -70,6 +70,7 @@ OBJS = $(PLUGIN).o \
extensions/cairoimage.o \
extensions/curlfuncs.o \
extensions/fontmanager.o \
extensions/globaltimers.o \
extensions/imagecache.o \
extensions/helpers.o \
extensions/imageloader.o \
@ -80,7 +81,6 @@ OBJS = $(PLUGIN).o \
extensions/skinsetup.o \
extensions/skinrepo.o \
extensions/extrecinfo.o \
extensions/timers.o \
coreengine/animation.o \
coreengine/attribute.o \
coreengine/attributes.o \
@ -138,7 +138,8 @@ $(SOFILE): SUB_LIBS = libskindesignerapi/libskindesignerapi.so.$(shell pkg-confi
### Implicit rules:
%.o: %.c
$(CXX) $(CXXFLAGS) -std=c++11 -c $(DEFINES) $(SUB_DEFINES) $(INCLUDES) -o $@ $<
@echo CC $@
$(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) -std=c++11 -c $(DEFINES) $(SUB_DEFINES) $(INCLUDES) -o $@ $<
### Dependencies:
@ -158,17 +159,21 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po
msgfmt -c -o $@ $<
@echo MO $@
$(Q)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 $^`
@echo GT $@
$(Q)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 $@ $<
@echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
install -D -m644 $< $@
@echo IN $@
$(Q)install -D -m644 $< $@
.PHONY: i18n
i18n: $(I18Nmo) $(I18Npot)
@ -178,10 +183,12 @@ install-i18n: $(I18Nmsgs)
### Targets:
$(SOFILE): $(OBJS)
$(CXX) $(CXXFLAGS) -std=c++11 $(LDFLAGS) -shared $(OBJS) $(LIBS) $(SUB_LIBS) -o $@
@echo LD $@
$(Q)$(CXX) $(CXXFLAGS) -std=c++11 $(LDFLAGS) -shared $(OBJS) $(LIBS) $(SUB_LIBS) -o $@
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
@echo IN $@
$(Q)install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
install-themes:
mkdir -p $(DESTDIR)$(VDRCONFDIR)/themes
@ -197,7 +204,7 @@ install-scripts:
mkdir -p $(DESTDIR)$(SKINDESIGNER_SCRIPTDIR)
cp -r scripts/* $(DESTDIR)$(SKINDESIGNER_SCRIPTDIR)
install: install-subprojects install-lib install-i18n install-themes install-skins install-scripts
install: install-lib install-i18n install-themes install-skins install-scripts install-subprojects
dist: $(I18Npo) clean
@-rm -rf $(TMPDIR)/$(ARCHIVE)

7
README
View File

@ -56,7 +56,7 @@ the library has to be proper installed on your system.
With a "make install" both the plugin and the library are installed on your
system. The destination where the library will be installed can be set with
the PREFIX parameter: "PREFIX=/usr make install". Default of PREFIX is
/usr/local.
/usr/local.
After installation check if libskindesignerapi.pc is correctly found in your
PKG_CONFIG_PATH. Other Plugins using the library issue the following
@ -68,6 +68,11 @@ pkg-config --modversion libskindesignerapi
Note that skindesigner itself and all plugins which use libSkindesignerAPI have to
be build against the same major verison of the library to be compatible.
If you like to disable the possibility to install skins from skindesigner setup
menu, you can enable the option in the makefile or set the option
DO_NOT_USE_SKININSTALLER manually via CPP Flags:
make CPPFLAGS="-DDO_NOT_USE_SKININSTALLER"
After installation you have to care about the paths for the XML skins and epg images.
The following paths can be set at startup:

View File

@ -16,11 +16,14 @@ cDesignerConfig::cDesignerConfig() {
debugImageLoading = 0;
replaceDecPoint = false;
//settings for rerun display
useSubtitleRerun = 0;
rerunAmount = 10;
rerunDistance = 2;
rerunMaxChannel = 0;
//max number of custom int and string tokens
numCustomTokens = 10;
//Frames per Second to display animations
FPS = 50;
//remember current skin and theme, osd size and osd fonts
SetSkin();
SetOSDSize();
@ -47,7 +50,9 @@ void cDesignerConfig::SetPathes(void) {
epgImagePath = cString::sprintf("%s/epgimages/", cPlugin::CacheDirectory(PLUGIN_NAME_I18N));
dsyslog("skindesigner: using Skin Directory %s", *skinPath);
#ifndef DO_NOT_USE_SKININSTALLER
dsyslog("skindesigner: using Installer Skin Directory %s", *installerSkinPath);
#endif
dsyslog("skindesigner: using common ChannelLogo Directory %s", *logoPath);
dsyslog("skindesigner: using EPG Images Directory %s", *epgImagePath);
@ -99,7 +104,10 @@ void cDesignerConfig::ReadSkinFolder(cString &skinFolder, vector<string> *contai
while (dirEntry = readdir(folder)) {
string dirEntryName = dirEntry->d_name;
int dirEntryType = dirEntry->d_type;
if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || !dirEntryName.compare("skinrepositories") || (dirEntryType != DT_DIR && dirEntryType != DT_LNK))
cString subfolder = cString::sprintf("%s%s", *skinFolder, dirEntryName.c_str());
if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || !dirEntryName.compare("skinrepositories"))
continue;
if (dirEntryType != DT_DIR && dirEntryType != DT_LNK && !DirectoryOk(*subfolder, false))
continue;
container->push_back(dirEntryName);
}
@ -110,10 +118,13 @@ void cDesignerConfig::ReadSkinFolder(cString &skinFolder, vector<string> *contai
void cDesignerConfig::ReadSkins(void) {
ReadSkinFolder(skinPath, &deliveredSkins);
#ifndef DO_NOT_USE_SKININSTALLER
ReadSkinFolder(installerSkinPath, &installerSkins);
#endif
for (vector<string>::iterator it = deliveredSkins.begin(); it != deliveredSkins.end(); it++) {
skins.push_back(*it);
}
#ifndef DO_NOT_USE_SKININSTALLER
for (vector<string>::iterator it = installerSkins.begin(); it != installerSkins.end(); it++) {
string instSkin = *it;
bool found = false;
@ -126,6 +137,7 @@ void cDesignerConfig::ReadSkins(void) {
if (!found)
skins.push_back(instSkin);
}
#endif
}
void cDesignerConfig::ClearSkinSetups(void) {
@ -335,9 +347,11 @@ void cDesignerConfig::SetSkinSetupParameters(void) {
}
void cDesignerConfig::ReadSkinRepos(void) {
#ifndef DO_NOT_USE_SKININSTALLER
skinRepos.Init(*installerSkinPath);
skinRepos.Read(*installerSkinPath);
dsyslog("skindesigner: read %d skinrepositories from %s", skinRepos.Count(), *installerSkinPath);
#endif
}
bool cDesignerConfig::CheckVersion(string name, string &neededVersion) {
@ -354,7 +368,7 @@ bool cDesignerConfig::CheckVersion(string name, string &neededVersion) {
}
splitstring ver(version.c_str());
vector<string> tokensVer = ver.split('.', 1);
if (tokensVer.size() != 3) {
if (tokensVer.size() < 3) {
esyslog("skindesigner: incorrect version definition: %s", version.c_str());
return false;
}
@ -448,6 +462,16 @@ bool cDesignerConfig::OsdSizeChanged(void) {
return false;
}
// If softhddevice is suspended, it gives the video size 0x0
// We use this for detect a play mode change and drop the cache, because it is corrupted after being suspended
bool cDesignerConfig::PlayModeChanged(void) {
if (mode_changed) {
mode_changed = 0;
return true;
}
return false;
}
void cDesignerConfig::SetOSDFonts(void) {
fontFix = Setup.FontFix;
fontOsd = Setup.FontOsd;
@ -497,10 +521,12 @@ bool cDesignerConfig::SetupParse(const char *Name, const char *Value) {
else if (!strcasecmp(Name, "LimitChannelLogoCache")) limitLogoCache = atoi(Value);
else if (!strcasecmp(Name, "NumberLogosInitially")) numLogosPerSizeInitial = atoi(Value);
else if (!strcasecmp(Name, "NumberLogosMax")) numLogosMax = atoi(Value);
else if (!strcasecmp(Name, "UseSubtitleRerun")) useSubtitleRerun = atoi(Value);
else if (!strcasecmp(Name, "RerunAmount")) rerunAmount = atoi(Value);
else if (!strcasecmp(Name, "RerunDistance")) rerunDistance = atoi(Value);
else if (!strcasecmp(Name, "RerunMaxChannel")) rerunMaxChannel = atoi(Value);
else if (!strcasecmp(Name, "NumCustomTokens")) numCustomTokens = atoi(Value);
else if (!strcasecmp(Name, "FPS")) FPS = atoi(Value);
else pluginSetupParam = false;
if (!pluginSetupParam) {

View File

@ -92,6 +92,7 @@ public:
bool SkinChanged(void);
void SetOSDSize(void);
bool OsdSizeChanged(void);
bool PlayModeChanged(void);
void SetOSDFonts(void);
bool OsdFontsChanged(void);
void SetOsdLanguage(void) { osdLanguage = Setup.OSDLanguage; };
@ -110,12 +111,15 @@ public:
int limitLogoCache;
int numLogosMax;
int debugImageLoading;
int useSubtitleRerun;
int rerunAmount;
int rerunDistance;
int rerunMaxChannel;
int numCustomTokens;
int FPS;
//TemplateReload on Setup Close
bool setupCloseDoReload;
int mode_changed;
};
#ifdef DEFINE_CONFIG

View File

@ -1,219 +1,40 @@
#include "../config.h"
#include "animation.h"
#include <math.h>
/******************************************************************
* cAnimation
* cDetacher
******************************************************************/
cAnimation::cAnimation(cScrollable *scrollable) : cThread("scroller") {
this->scrollable = scrollable;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = false;
doFlush = true;
blinkFunc = -1;
}
cAnimation::cAnimation(cDetachable *detachable, bool wait, bool animation) : cThread("detached") {
this->scrollable = NULL;
cDetacher::cDetacher(cDetachable *detachable, bool wait, bool animation) : cThread("detacher thread") {
this->detachable = detachable;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = wait;
keepSleeping = false;
doAnimation = animation;
modeIn = false;
doFlush = true;
blinkFunc = -1;
}
cAnimation::cAnimation(cFadable *fadable, bool fadein) : cThread("fadable") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = fadable;
this->shiftable = NULL;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = fadein;
doFlush = true;
blinkFunc = -1;
}
cAnimation::cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin, bool doFlush) : cThread("shiftable") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = shiftable;
this->blinkable = NULL;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = shiftin;
shiftstart = start;
shiftend = end;
this->doFlush = doFlush;
blinkFunc = -1;
}
cAnimation::cAnimation(cBlinkable *blinkable, int func) : cThread("blinking") {
this->scrollable = NULL;
this->detachable = NULL;
this->fadable = NULL;
this->shiftable = NULL;
this->blinkable = blinkable;
waitOnWakeup = false;
keepSleeping = false;
doAnimation = true;
modeIn = false;
doFlush = true;
blinkFunc = func;
}
cAnimation::~cAnimation(void) {
cDetacher::~cDetacher(void) {
sleepWait.Signal();
Cancel(2);
}
void cAnimation::WakeUp(void) {
void cDetacher::WakeUp(void) {
sleepWait.Signal();
}
void cAnimation::ResetSleep(void) {
void cDetacher::ResetSleep(void) {
keepSleeping = true;
sleepWait.Signal();
}
void cAnimation::Stop(bool deletePixmaps) {
void cDetacher::Stop(bool deletePixmaps) {
sleepWait.Signal();
Cancel(2);
if (scrollable && deletePixmaps)
scrollable->StopScrolling();
}
void cAnimation::Action(void) {
if (scrollable) {
Scroll();
} else if (detachable) {
Detach();
} else if (fadable) {
Fade();
} else if (shiftable) {
Shift();
} else if (blinkable) {
Blink();
}
}
void cAnimation::Sleep(int duration) {
//sleep should wake up itself, so no infinit wait allowed
if (duration <= 0)
void cDetacher::Action(void) {
if (!detachable) {
return;
do {
keepSleeping = false;
sleepWait.Wait(duration);
} while (keepSleeping);
}
void cAnimation::Wait(void) {
//wait has to be waked up from outside
sleepWait.Wait(0);
}
void cAnimation::Scroll(void) {
int delay = scrollable->ScrollDelay();
Sleep(delay);
if (!Running()) return;
eOrientation orientation = scrollable->ScrollOrientation();
int scrollTotal = 0;
if (orientation == eOrientation::horizontal) {
scrollTotal = scrollable->ScrollWidth();
} else if (orientation == eOrientation::vertical) {
scrollTotal = scrollable->ScrollHeight();
}
eScrollMode mode = scrollable->ScrollMode();
bool carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false;
eScrollSpeed speed = scrollable->ScrollSpeed();
int frameTime = 30;
if (speed == eScrollSpeed::slow)
frameTime = 50;
else if (speed == eScrollSpeed::medium)
frameTime = 30;
else if (speed == eScrollSpeed::fast)
frameTime = 15;
if (!Running()) return;
scrollable->StartScrolling();
int drawPortX = 0;
int drawPortY = 0;
int scrollDelta = 1;
bool doSleep = false;
while (Running()) {
if (doSleep) {
Sleep(delay);
doSleep = false;
}
if (!Running()) return;
uint64_t now = cTimeMs::Now();
cPoint drawPortPoint(0,0);
if (orientation == eOrientation::horizontal) {
drawPortX -= scrollDelta;
if (abs(drawPortX) > scrollTotal) {
Sleep(delay);
if (carriageReturn) {
drawPortX = 0;
doSleep = true;
} else {
scrollDelta *= -1;
drawPortX -= scrollDelta;
}
}
drawPortPoint.SetX(drawPortX);
} else if (orientation == eOrientation::vertical) {
drawPortY -= scrollDelta;
if (abs(drawPortY) > scrollTotal) {
Sleep(delay);
drawPortY = 0;
doSleep = true;
}
drawPortPoint.SetY(drawPortY);
}
if (!Running()) return;
scrollable->SetDrawPort(drawPortPoint);
if (!Running()) return;
scrollable->Flush();
if (orientation == eOrientation::horizontal && !carriageReturn && (drawPortX == 0)) {
scrollDelta *= -1;
doSleep = true;
}
int delta = cTimeMs::Now() - now;
if (delta < frameTime)
Sleep(frameTime - delta);
}
}
void cAnimation::Detach(void) {
if (waitOnWakeup) {
Wait();
int delay = 50 + detachable->Delay();
@ -223,11 +44,9 @@ void cAnimation::Detach(void) {
if (delay > 0)
Sleep(delay);
}
if (!Running()) return;
detachable->ParseDetached();
if (!Running()) return;
detachable->RenderDetached();
if (!Running()) return;
if (!doAnimation)
detachable->Flush();
if (!Running()) return;
@ -236,136 +55,625 @@ void cAnimation::Detach(void) {
}
}
void cAnimation::Fade(void) {
int fadetime = fadable->FadeTime();
int frametime = 1000 / FPS;
int step = 100.0f / ((double)fadetime / (double)frametime);
uint64_t start = cTimeMs::Now();
int transparency = 0;
if (modeIn) {
transparency = 100 - step;
} else {
transparency = step;
}
//wait configured delay if not already done by detacher
if (!fadable->Detached()) {
int delay = fadable->Delay();
if (delay > 0)
Sleep(delay);
}
while (Running() || !modeIn) {
uint64_t now = cTimeMs::Now();
if (Running() || !modeIn)
fadable->SetTransparency(transparency, !modeIn);
if (Running() || !modeIn)
fadable->Flush();
int delta = cTimeMs::Now() - now;
if ((Running() || !modeIn) && (delta < frametime)) {
Sleep(frametime - delta);
}
if ((int)(now - start) > fadetime) {
if ((Running() && modeIn) && transparency > 0) {
fadable->SetTransparency(0);
fadable->Flush();
} else if (!modeIn && transparency < 100) {
fadable->SetTransparency(100, true);
fadable->Flush();
}
break;
}
if (modeIn) {
transparency -= step;
if (transparency < 0)
transparency = 0;
} else {
transparency += step;
if (transparency > 100)
transparency = 100;
}
}
}
void cAnimation::Shift(void) {
int shifttime = shiftable->ShiftTime();
eShiftMode mode = (eShiftMode)shiftable->ShiftMode();
//in shiftmode slowedDown shifting is done starting with slowratio % faster
//at start. Then speed reduces linear to (100 - slowratio)% at end
//for me 60 is a nice value :-)
int slowRatio = 60;
int frametime = 1000 / FPS;
int steps = (double)shifttime / (double)frametime;
if (steps < 2)
void cDetacher::Sleep(int duration) {
if (duration <= 0)
return;
int stepXLinear = 0;
int stepYLinear = 0;
if (shiftstart.X() == shiftend.X()) {
stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps;
} else if (shiftstart.Y() == shiftend.Y()) {
stepXLinear = (shiftend.X() - shiftstart.X()) / steps;
} else {
stepXLinear = (shiftend.X() - shiftstart.X()) / steps;
stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps;
}
int stepX = stepXLinear;
int stepY = stepYLinear;
do {
keepSleeping = false;
sleepWait.Wait(duration);
} while (keepSleeping);
}
cPoint pos;
if (modeIn)
pos = shiftstart;
void cDetacher::Wait(void) {
//wait has to be waked up from outside
sleepWait.Wait(0);
}
/******************************************************************
* cAnimaton
******************************************************************/
cAnimation::cAnimation(void) {
started = 0;
finished = false;
persistent = false;
frametime = 1000 / config.FPS;
}
cAnimation::~cAnimation(void) {
}
/******************************************************************
* cScroller
******************************************************************/
cScroller::cScroller(cScrollable *scrollable) {
this->scrollable = scrollable;
paused = true;
pauseTime = 0;
scrollingStarted = false;
secondDelay = false;
delScrollPix = true;
Init();
}
cScroller::~cScroller(void) {
}
void cScroller::Init(void) {
delay = scrollable->ScrollDelay();
orientation = scrollable->ScrollOrientation();
if (orientation == eOrientation::horizontal) {
scrollLength = scrollable->ScrollWidth();
} else if (orientation == eOrientation::vertical) {
scrollLength = scrollable->ScrollHeight();
}
eScrollMode mode = scrollable->ScrollMode();
carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false;
drawPortX = 0.0f;
drawPortY = 0.0f;
eScrollSpeed speed = scrollable->ScrollSpeed();
if (speed == eScrollSpeed::slow)
scrollDelta = 0.5f;
else if (speed == eScrollSpeed::fast)
scrollDelta = 2.0f;
else
pos = shiftend;
scrollDelta = 1.0f;
}
//wait configured delay if not already done by detacher
if (!shiftable->Detached()) {
int delay = shiftable->Delay();
if (delay > 0)
Sleep(delay);
void cScroller::Reactivate(void) {}
void cScroller::SetInitial(void) {
scrollable->SetScrollingStarted();
}
bool cScroller::Pause(void) {
if (!paused)
return false;
if ((pauseTime + frametime) > delay) {
paused = false;
pauseTime = 0;
return false;
}
pauseTime += frametime;
return true;
}
bool cScroller::Overflow(void) {
if (orientation == eOrientation::horizontal) {
if (!carriageReturn && (drawPortX >= 1)) {
drawPortX = 0;
scrollDelta *= -1;
paused = true;
return true;
}
if (carriageReturn && (drawPortX >= 0) && secondDelay) {
cPoint drawPortPoint(drawPortX,0);
scrollable->SetDrawPort(drawPortPoint);
drawPortX = -1;
paused = true;
secondDelay = false;
return true;
}
if (abs((int)drawPortX) < scrollLength)
return false;
if (carriageReturn) {
drawPortX = 0;
secondDelay = true;
} else {
scrollDelta *= -1;
drawPortX -= scrollDelta;
}
} else if (orientation == eOrientation::vertical) {
if ((drawPortY >= 0) && secondDelay) {
cPoint drawPortPoint(0, drawPortY);
scrollable->SetDrawPort(drawPortPoint);
drawPortY = -1;
paused = true;
secondDelay = false;
return true;
}
if (abs((int)drawPortY) < scrollLength)
return false;
secondDelay = true;
drawPortY = 0;
}
paused = true;
return true;
}
void cScroller::SetFinished(void) {
finished = true;
if (delScrollPix) {
scrollable->StopScrolling();
}
}
bool cScroller::Tick(void) {
if (finished) {
return false;
}
shiftable->SetStartShifting();
uint64_t start = cTimeMs::Now();
while (Running() || !modeIn) {
uint64_t now = cTimeMs::Now();
if (Running() || !modeIn)
shiftable->SetPosition(pos, shiftend);
if ((Running() || !modeIn) && doFlush)
shiftable->Flush();
int delta = cTimeMs::Now() - now;
if ((Running() || !modeIn) && (delta < frametime)) {
cCondWait::SleepMs(frametime - delta);
if (Pause())
return true;
if (!scrollingStarted) {
scrollable->StartScrolling();
scrollingStarted = true;
}
if (Overflow())
return true;
cPoint drawPortPoint(0,0);
if (orientation == eOrientation::horizontal) {
drawPortX -= scrollDelta;
drawPortPoint.SetX(drawPortX);
} else if (orientation == eOrientation::vertical) {
drawPortY -= scrollDelta;
drawPortPoint.SetY(drawPortY);
}
scrollable->SetDrawPort(drawPortPoint);
return true;
};
/******************************************************************
* cFader
******************************************************************/
cFader::cFader(cFadable *fadable) {
this->fadable = fadable;
fadein = true;
fadetime = fadable->FadeTime();
step = 100.0f / ((double)fadetime / (double)frametime);
transparency = 100;
hideWhenFinished = false;
}
cFader::~cFader(void) {
}
void cFader::Reactivate(void) {
started = 0;
finished = false;
fadein = false;
}
void cFader::SetInitial(void) {
fadable->SetTransparency(transparency);
}
void cFader::SetFadeOut(void) {
fadein = false;
transparency = 0;
}
void cFader::SetFinished(void) {
finished = true;
if (hideWhenFinished)
fadable->SetTransparency(100);
}
bool cFader::Tick(void) {
if (finished) {
if (fadein)
fadable->SetTransparency(0);
else
fadable->SetTransparency(100);
return false;
}
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > fadetime) {
if (fadein)
fadable->SetTransparency(0);
else
fadable->SetTransparency(100);
finished = true;
return false;
}
fadable->SetTransparency(transparency);
if (fadein) {
transparency -= step;
} else {
transparency += step;
}
return true;
};
/******************************************************************
* cShifter
******************************************************************/
cShifter::cShifter(cShiftable *shiftable) {
this->shiftable = shiftable;
step = 0;
shiftin = true;
shifttime = 0;
x = 0.0f;
y = 0.0f;
stepXLinear = 0.0f;
stepYLinear = 0.0f;
stepsFast = 0;
stepXFast = 0.0f;
stepXSlow = 0.0f;
stepYFast = 0.0f;
stepYSlow = 0.0f;
Init();
}
cShifter::~cShifter(void) {
}
void cShifter::Init(void) {
shifttime = shiftable->ShiftTime();
mode = (eShiftMode)shiftable->ShiftMode();
shiftable->ShiftPositions(&start, &end);
int steps = (double)shifttime / (double)frametime;
if (steps <= 0) steps = 1;
float percentFast = 33.3f;
float distanceFast = 85.0f;
stepsFast = (float)steps * percentFast / 100.0f;
if (start.X() == end.X()) {
stepYLinear = (float)(end.Y() - start.Y()) / (float)steps;
stepYFast = (float)(end.Y() - start.Y()) * distanceFast / 100.0f / (float)stepsFast;
stepYSlow = (float)(end.Y() - start.Y()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
} else if (start.Y() == end.Y()) {
stepXLinear = (float)(end.X() - start.X()) / (float)steps;
stepXFast = (float)(end.X() - start.X()) * distanceFast / 100.0f / (float)stepsFast;
stepXSlow = (float)(end.X() - start.X()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
} else {
stepXLinear = (float)(end.X() - start.X()) / (float)steps;
stepXFast = (float)(end.X() - start.X()) * distanceFast / 100.0f / (float)stepsFast;
stepXSlow = (float)(end.X() - start.X()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
stepYLinear = (float)(end.Y() - start.Y()) / (float)steps;
stepYFast = (float)(end.Y() - start.Y()) * distanceFast / 100.0f / (float)stepsFast;
stepYSlow = (float)(end.Y() - start.Y()) * (100.0f - distanceFast) / 100.0f / (float)(steps-stepsFast);
}
if (shiftin) {
x = start.X();
y = start.Y();
} else {
x = end.X();
y = end.Y();
}
}
void cShifter::Reactivate(void) {
started = 0;
finished = false;
shiftin = false;
step = 0;
Init();
}
void cShifter::SetInitial(void) {
cPoint pos(x, y);
shiftable->SetPosition(pos, end);
}
void cShifter::NextPosition(void) {
if (mode == eShiftMode::linear) {
if (shiftin) {
x += stepXLinear;
y += stepYLinear;
} else {
x -= stepXLinear;
y -= stepYLinear;
}
if ((int)(now - start) > shifttime) {
if ((Running() && modeIn) && pos != shiftend) {
shiftable->SetPosition(shiftend, shiftend);
shiftable->Flush();
} else if (mode == eShiftMode::slowedDown) {
if (shiftin) {
if (step <= stepsFast) {
x += stepXFast;
y += stepYFast;
} else {
x += stepXSlow;
y += stepYSlow;
}
} else {
if (step <= stepsFast) {
x -= stepXFast;
y -= stepYFast;
} else {
x -= stepXSlow;
y -= stepYSlow;
}
}
}
}
bool cShifter::Tick(void) {
if (finished)
return false;
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > shifttime) {
if (shiftin)
shiftable->SetPosition(end, end);
else
shiftable->SetPosition(start, end);
finished = true;
return false;
}
cPoint pos(x, y);
shiftable->SetPosition(pos, end);
step++;
NextPosition();
return true;
};
/******************************************************************
* cListShifter
******************************************************************/
cListShifter::cListShifter(cListShiftable *shiftable) {
this->shiftable = shiftable;
shifttime = shiftable->ListShiftTime();
distance = shiftable->ShiftDistance();
orientation = shiftable->ShiftOrientation();
int steps = (double)shifttime / (double)frametime;
if (steps <= 0) steps = 1;
step = distance / steps;
shiftin = true;
fromtop = true;
}
cListShifter::~cListShifter(void) {
}
void cListShifter::Reactivate(void) {}
void cListShifter::SetInitial(void) {
if (shiftin) {
if (orientation == eOrientation::horizontal) {
if (fromtop) {
pos.SetX(-1 * distance);
pos.SetY(0);
} else {
pos.SetX(distance);
pos.SetY(0);
}
} else {
if (fromtop) {
pos.SetX(0);
pos.SetY(-1 * distance);
} else {
pos.SetX(0);
pos.SetY(distance);
}
}
}
shiftable->SetIndicatorPosition(pos);
}
void cListShifter::NextPosition(void) {
int x = pos.X();
int y = pos.Y();
if (orientation == eOrientation::horizontal) {
if (fromtop) {
pos.SetX(x+step);
} else {
pos.SetX(x-step);
}
} else {
if (fromtop) {
pos.SetY(y+step);
} else {
pos.SetY(y-step);
}
}
}
void cListShifter::EndPosition(void) {
if (shiftin) {
pos.SetX(0);
pos.SetY(0);
} else {
if (orientation == eOrientation::horizontal) {
pos.SetX(distance);
} else {
pos.SetY(distance);
}
}
shiftable->SetIndicatorPosition(pos);
}
bool cListShifter::Tick(void) {
if (finished) {
EndPosition();
return false;
}
if (!started) {
started = cTimeMs::Now();
}
if ((int)(cTimeMs::Now() - started) > shifttime) {
EndPosition();
finished = true;
return false;
}
shiftable->SetIndicatorPosition(pos);
NextPosition();
return true;
};
/******************************************************************
* cBlinker
******************************************************************/
cBlinker::cBlinker(cBlinkable *blinkable, int blinkFunc) {
this->blinkable = blinkable;
this->blinkFunc = blinkFunc;
freq = blinkable->BlinkFreq(blinkFunc);
blinkOn = false;
paused = true;
pauseTime = 0;
}
cBlinker::~cBlinker(void) {
}
void cBlinker::Reactivate(void) {}
void cBlinker::SetInitial(void) {}
bool cBlinker::Pause(void) {
if (!paused)
return false;
if ((pauseTime + frametime) > freq) {
paused = false;
pauseTime = 0;
return false;
}
pauseTime += frametime;
return true;
}
bool cBlinker::Tick(void) {
if (finished)
return false;
if (Pause())
return true;
blinkable->DoBlink(blinkFunc, blinkOn);
blinkOn = !blinkOn;
paused = true;
pauseTime = 0;
return true;
};
/******************************************************************
* cAnimator
******************************************************************/
cAnimator::cAnimator(cSdOsd *osd) : cThread("animator thread") {
this->osd = osd;
timeneeded = 0;
timeslice = 1000 / config.FPS;
}
cAnimator::~cAnimator(void) {
Stop();
}
void cAnimator::Sleep(uint64_t start) {
timeneeded = cTimeMs::Now() - start;
int sleepTime = (timeslice - timeneeded) > 0 ? timeslice - timeneeded : 0;
if (sleepTime)
sleepWait.Wait(sleepTime);
}
void cAnimator::DoTick(bool &animActive) {
animLock.Lock();
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (Running()) {
bool currentAnimActive = animation->Tick();
animActive = animActive || currentAnimActive;
}
}
animLock.Unlock();
}
/*****************************************************************************************
* Cleanup Anims
* removes finished anims
* remembers persistent anims
*****************************************************************************************/
void cAnimator::CleanupAnims(void) {
bool found;
animLock.Lock();
do {
found = false;
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (!animation->Finished())
continue;
if (animation->Persistent()) {
animations.Del(animation, false);
animationsPersistent.Add(animation);
} else {
animations.Del(animation);
}
found = true;
break;
}
if (mode == eShiftMode::slowedDown) {
double t = (double)(now - start) / (double)shifttime;
double factor = 1.0f + (double)slowRatio / 100.0f - 2.0f * ((double)slowRatio / 100.0f) * t;
stepX = stepXLinear * factor;
stepY = stepYLinear * factor;
}
if (modeIn) {
pos.Set(pos.X() + stepX, pos.Y() + stepY);
} else {
pos.Set(pos.X() - stepX, pos.Y() - stepY);
}
}
shiftable->SetEndShifting();
} while (found);
animLock.Unlock();
}
void cAnimation::Blink(void) {
int freq = blinkable->BlinkFreq(blinkFunc);
bool blinkOn = false;
while (Running()) {
Sleep(freq);
if (Running())
blinkable->DoBlink(blinkFunc, blinkOn);
if (Running())
blinkable->Flush();
blinkOn = !blinkOn;
/*****************************************************************************************
* Main Loop
*****************************************************************************************/
void cAnimator::Action(void) {
while(Running()) {
bool animActive = false;
uint64_t start = cTimeMs::Now();
DoTick(animActive); if (!Running()) break;
osd->Flush(); if (!Running()) break;
CleanupAnims(); if (!Running()) break;
if (!animActive) {
pauseWait.Wait();
} else {
Sleep(start);
}
}
}
/*****************************************************************************************
* Add Animation
* if startAnim is set to true, main loop gets waked up
*****************************************************************************************/
void cAnimator::AddAnimation(cAnimation *animation, bool startAnim) {
animation->SetInitial();
animLock.Lock();
animations.Ins(animation);
animLock.Unlock();
if (startAnim)
pauseWait.Signal();
}
/*****************************************************************************************
* Remove Animation
* animation will be set to finished and removed later by Cleanup()
*****************************************************************************************/
void cAnimator::RemoveAnimation(cAnimation *remove) {
animLock.Lock();
for (cAnimation *animation = animations.First(); animation; animation = animations.Next(animation)) {
if (animation == remove) {
animation->SetFinished();
break;
}
}
animLock.Unlock();
}
/*****************************************************************************************
* Finish Main Loop
*****************************************************************************************/
void cAnimator::Stop(void) {
if (!Running())
return;
Cancel(-1);
pauseWait.Signal();
sleepWait.Signal();
Cancel(2);
}
/*****************************************************************************************
* shift or fade out persistent animations
*****************************************************************************************/
void cAnimator::Finish(void) {
bool animActive = true;
bool reactivate = true;
while(animActive) {
animActive = false;
uint64_t start = cTimeMs::Now();
animLock.Lock();
for (cAnimation *animation = animationsPersistent.First(); animation; animation = animationsPersistent.Next(animation)) {
if (reactivate)
animation->Reactivate();
bool currentAnimActive = animation->Tick();
animActive = animActive || currentAnimActive;
}
animLock.Unlock();
reactivate = false;
if (!animActive)
break;
osd->Flush();
Sleep(start);
}
}

View File

@ -4,11 +4,64 @@
#include <vdr/skins.h>
#include <vdr/thread.h>
#include "definitions.h"
#define FPS 50
#include "osdwrapper.h"
/******************************************************************
* cScrollable
* Detaching
******************************************************************/
class cDetachable {
protected:
cDetachable(void) {};
~cDetachable(void) {};
public:
virtual int Delay(void) = 0;
virtual void StartAnimation(void) = 0;
virtual void ParseDetached(void) = 0;
virtual void RenderDetached(void) = 0;
virtual void Flush(void) = 0;
};
class cDetacher : public cThread, public cListObject {
private:
cCondWait sleepWait;
cDetachable *detachable;
bool waitOnWakeup;
bool keepSleeping;
bool doAnimation;
void Sleep(int duration);
void Wait(void);
virtual void Action(void);
public:
cDetacher(cDetachable *detachable, bool wait, bool animation);
~cDetacher(void);
void WakeUp(void);
void ResetSleep(void);
void Stop(bool deletePixmaps);
};
/******************************************************************
* cAnimation
******************************************************************/
class cAnimation : public cListObject {
protected:
uint64_t started;
bool finished;
bool persistent;
int frametime;
public:
cAnimation(void);
virtual ~cAnimation(void);
virtual void SetInitial(void) = 0;
virtual void Reactivate(void) = 0;
virtual bool Tick(void) = 0;
bool Finished(void) { return finished; };
virtual void SetFinished(void) { finished = true; };
void SetPersistent(void) { persistent = true; };
bool Persistent(void) { return persistent; };
};
/******************************************************************
* Scrolling
******************************************************************/
class cScrollable {
protected:
@ -21,62 +74,144 @@ public:
virtual eScrollMode ScrollMode(void) = 0;
virtual eScrollSpeed ScrollSpeed(void) = 0;
virtual eOrientation ScrollOrientation(void) = 0;
virtual void SetScrollingStarted(void) = 0;
virtual void StartScrolling(void) = 0;
virtual void StopScrolling(void) = 0;
virtual void SetDrawPort(cPoint &point) = 0;
virtual void Flush(void) = 0;
};
/******************************************************************
* cDetachable
******************************************************************/
class cDetachable {
protected:
cDetachable(void) {};
~cDetachable(void) {};
class cScroller : public cAnimation {
private:
cScrollable *scrollable;
int delay;
bool paused;
int pauseTime;
bool scrollingStarted;
bool secondDelay;
eOrientation orientation;
int scrollLength;
bool carriageReturn;
float drawPortX;
float drawPortY;
float scrollDelta;
bool delScrollPix;
void Init(void);
bool Pause(void);
bool Overflow(void);
public:
virtual int Delay(void) = 0;
virtual void ParseDetached(void) = 0;
virtual void RenderDetached(void) = 0;
virtual void StartAnimation(void) = 0;
virtual void Flush(void) = 0;
cScroller(cScrollable *scrollable);
~cScroller(void);
void SetInitial(void);
void Reactivate(void);
void SetFinished(void);
void UnsetDelScrollPix(void) { delScrollPix = false; };
bool Tick(void);
};
/******************************************************************
* cFadable
* Fading
******************************************************************/
class cFadable {
protected:
cFadable(void) {};
~cFadable(void) {};
public:
virtual bool Detached(void) = 0;
virtual int Delay(void) = 0;
virtual int FadeTime(void) = 0;
virtual void SetTransparency(int transparency, bool force = false) = 0;
virtual void Flush(void) = 0;
};
class cFader : public cAnimation {
private:
cFadable *fadable;
bool fadein;
int fadetime;
int step;
int transparency;
bool hideWhenFinished;
public:
cFader(cFadable *fadable);
~cFader(void);
void SetInitial(void);
void Reactivate(void);
void SetFadeOut(void);
void SetFinished(void);
void SetHideWhenFinished(void) { hideWhenFinished = true; };
bool Tick(void);
};
/******************************************************************
* cShiftable
* Shifting
******************************************************************/
class cShiftable {
protected:
cShiftable(void) {};
~cShiftable(void) {};
public:
virtual bool Detached(void) = 0;
virtual int Delay(void) = 0;
virtual int ShiftTime(void) = 0;
virtual int ShiftMode(void) = 0;
virtual void ShiftPositions(cPoint *start, cPoint *end) = 0;
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false) = 0;
virtual void SetStartShifting(void) = 0;
virtual void SetEndShifting(void) = 0;
virtual void Flush(void) = 0;
};
class cListShiftable {
protected:
cListShiftable(void) {};
~cListShiftable(void) {};
public:
virtual int ListShiftTime(void) = 0;
virtual int ShiftDistance(void) = 0;
virtual eOrientation ShiftOrientation(void) = 0;
virtual void SetIndicatorPosition(cPoint &position) = 0;
};
class cShifter : public cAnimation {
private:
cShiftable *shiftable;
bool shiftin;
cPoint start, end;
int shifttime;
eShiftMode mode;
int step;
float stepXLinear, stepYLinear;
int stepsFast;
float stepXFast, stepXSlow;
float stepYFast, stepYSlow;
float x, y;
void Init(void);
void NextPosition(void);
public:
cShifter(cShiftable *shiftable);
~cShifter(void);
void SetInitial(void);
void Reactivate(void);
bool Tick(void);
};
class cListShifter : public cAnimation {
private:
cListShiftable *shiftable;
bool shiftin;
bool fromtop;
int distance;
eOrientation orientation;
int shifttime;
int step;
cPoint pos;
void NextPosition(void);
void EndPosition(void);
public:
cListShifter(cListShiftable *shiftable);
~cListShifter(void);
void SetInitial(void);
void Reactivate(void);
void SetShiftOut(void) { shiftin = false; };
void SetDirection(bool fromTop) { fromtop = fromTop; };
bool Tick(void);
};
/******************************************************************
* cBlinkable
* Blinking
******************************************************************/
class cBlinkable {
protected:
@ -85,47 +220,49 @@ protected:
public:
virtual int BlinkFreq(int func) = 0;
virtual void DoBlink(int func, bool on) = 0;
virtual void Flush(void) = 0;
};
class cBlinker : public cAnimation {
private:
cBlinkable *blinkable;
int blinkFunc;
int freq;
bool blinkOn;
bool paused;
int pauseTime;
bool Pause(void);
public:
cBlinker(cBlinkable *blinkable, int blinkFunc);
~cBlinker(void);
void SetInitial(void);
void Reactivate(void);
bool Tick(void);
};
/******************************************************************
* cAnimation
* cAnimator
******************************************************************/
class cAnimation : public cThread, public cListObject {
class cAnimator : public cThread {
private:
cSdOsd *osd;
cCondWait sleepWait;
cScrollable *scrollable;
cDetachable *detachable;
cFadable *fadable;
cShiftable *shiftable;
cBlinkable *blinkable;
bool waitOnWakeup;
bool keepSleeping;
bool doAnimation;
bool modeIn;
int blinkFunc;
cPoint shiftstart;
cPoint shiftend;
bool doFlush;
void Sleep(int duration);
void Wait(void);
void Scroll(void);
void Detach(void);
void Blink(void);
protected:
cCondWait pauseWait;
int timeslice;
int timeneeded;
cMutex animLock;
cList<cAnimation> animations;
cList<cAnimation> animationsPersistent;
void Sleep(uint64_t start);
void DoTick(bool &animActive);
void CleanupAnims(void);
virtual void Action(void);
public:
cAnimation(cScrollable *scrollable);
cAnimation(cDetachable *detachable, bool wait, bool animation);
cAnimation(cFadable *fadable, bool fadein);
cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin, bool doFlush = true);
cAnimation(cBlinkable *blinkable, int func);
~cAnimation(void);
void WakeUp(void);
void ResetSleep(void);
void Fade(void);
void Shift(void);
void Stop(bool deletePixmaps);
cAnimator(cSdOsd *osd);
~cAnimator(void);
void AddAnimation(cAnimation *animation, bool startAnim = true);
void RemoveAnimation(cAnimation *remove);
void Stop(void);
void Finish(void);
};
#endif //__ANIMATION_H

View File

@ -30,6 +30,7 @@ cArea::cArea(void) {
attribs = new cAreaAttribs((int)eAreaAttribs::count);
scrolling = false;
isScrolling = false;
scrollingStarted = false;
scrollFunc = NULL;
blinking = false;
areaContainer = NULL;
@ -45,6 +46,7 @@ cArea::cArea(const cArea &other) {
attribs = new cAreaAttribs(*other.attribs);
//area container is set from outside during cloning of areacontainer
areaContainer = NULL;
scrollingStarted = false;
//scrolling is set from outside by ScrollFunc(), see below
scrolling = other.scrolling;
isScrolling = false;
@ -244,6 +246,7 @@ void cArea::Close(void) {
pix = NULL;
}
init = true;
scrollingStarted = false;
}
void cArea::Clear(bool forceClearBackground) {
@ -252,8 +255,21 @@ void cArea::Clear(bool forceClearBackground) {
}
StopBlinkers();
if (pix) {
pix->SetDrawPortPoint(cPoint(0,0));
pix->Fill(clrTransparent);
}
scrollingStarted = false;
}
void cArea::ClearWithoutIndicators(void) {
if (attribs->IndicatorArea()) {
return;
}
StopBlinkers();
if (pix) {
pix->Fill(clrTransparent);
}
scrollingStarted = false;
}
void cArea::Hide(void) {
@ -335,6 +351,23 @@ void cArea::SetTransparency(int transparency, bool absolute) {
}
}
void cArea::SetIndicatorTransparency(int transparency) {
if (!attribs->IndicatorArea())
return;
if (transparency < 0 || transparency > 100)
return;
int alpha = (100 - transparency)*255/100;
if (pix) {
pix->SetAlpha(alpha);
}
}
void cArea::SetIndicatorPosition(cPoint &pos) {
if (!attribs->IndicatorArea())
return;
SetDrawPort(pos);
}
bool cArea::Scrolling(void) {
if (!scrolling)
return false;
@ -425,8 +458,14 @@ void cArea::SetViewPort(cRect &vp) {
void cArea::SetPosition(cPoint &pos, cPoint &ref) {
if (!pix)
return;
int x = (attribs->X() - ref.X()) + pos.X();
int y = (attribs->Y() - ref.Y()) + pos.Y();
int x0 = attribs->X() == -1 ? 0 : attribs->X();
int y0 = attribs->Y() == -1 ? 0 : attribs->Y();
int x = (x0 - ref.X()) + pos.X();
int y = (y0 - ref.Y()) + pos.Y();
/* Enable for xineliboutput OSD Bug
if (x < 0) x = 0;
if (y < 0) y = 0;
*/
pix->SetViewPort(cRect(x, y, pix->ViewPort().Width(), pix->ViewPort().Height()));
}
@ -491,9 +530,6 @@ void cArea::Debug(bool full) {
}
}
void cArea::Flush(void) {
sdOsd->Flush();
}
/******************************************************************
* Private Functions
******************************************************************/
@ -515,11 +551,10 @@ void cArea::CreatePixmap(cRect drawPort) {
}
int layer = attribs->Layer();
cRect viewPort(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
cRect viewPort(attribs->X() == -1 ? 0 : attribs->X(), attribs->Y() == -1 ? 0 : attribs->Y(), attribs->Width(), attribs->Height());
pix = sdOsd->CreatePixmap(layer, viewPort, drawPort);
if (pix)
pix->Clear();
int pixTransparency = attribs->Transparency();
if (pixTransparency > 0) {
SetTransparency(pixTransparency, true);
@ -557,9 +592,9 @@ void cArea::StartBlinkers(void) {
continue;
}
if (f->Blinking()) {
cAnimation *blink = new cAnimation((cBlinkable*)this, func);
blinkers.Add(blink);
blink->Start();
cBlinker *blinker = new cBlinker((cBlinkable*)this, func);
blinkers.push_back(blinker);
cView::AddAnimation(blinker);
}
func++;
}
@ -567,7 +602,10 @@ void cArea::StartBlinkers(void) {
void cArea::StopBlinkers(void) {
blinking = false;
blinkers.Clear();
for (list<cBlinker*>::iterator it = blinkers.begin(); it != blinkers.end(); it++) {
cView::RemoveAnimation(*it);
}
blinkers.clear();
}
/******************************************************************
@ -691,6 +729,12 @@ void cAreaContainer::Clear(bool forceClearBackground) {
}
}
void cAreaContainer::ClearWithoutIndicators(void) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->ClearWithoutIndicators();
}
}
void cAreaContainer::Hide(void) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->Hide();
@ -720,6 +764,18 @@ void cAreaContainer::SetTransparency(int transparency, bool absolute) {
}
}
void cAreaContainer::SetIndicatorTransparency(int transparency) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetIndicatorTransparency(transparency);
}
}
void cAreaContainer::SetIndicatorPosition(cPoint &pos) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetIndicatorPosition(pos);
}
}
void cAreaContainer::SetViewPort(cRect &vp) {
for (cArea *area = areas.First(); area; area = areas.Next(area)) {
area->SetViewPort(vp);

View File

@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <list>
#include "osdwrapper.h"
#include "definitions.h"
@ -45,15 +46,19 @@ public:
virtual void Close(void) {};
virtual void StopBlinkers(void) {};
virtual void Clear(bool forceClearBackground = false) {};
virtual void ClearWithoutIndicators(void) {};
virtual void Hide(void) {};
virtual void Show(void) {};
virtual void Render(void) {};
virtual bool Execute(void) { return true; };
virtual void SetTransparency(int transparency, bool absolute = false) {};
virtual void SetIndicatorTransparency(int transparency) {};
virtual void SetViewPort(cRect &vp) {};
virtual void SetPosition(cPoint &pos, cPoint &ref) {};
virtual void SetIndicatorPosition(cPoint &pos) {};
virtual cRect CoveringArea(void) { return cRect::Null; };
virtual bool Scrolling(void) { return false; };
virtual bool ScrollingStarted(void) { return false; };
virtual cArea *ScrollingArea(void) { return NULL; };
virtual cFunction *GetFunction(const char *name) { return NULL; };
virtual const char *Name(void) { return NULL; };
@ -76,8 +81,9 @@ private:
cList<cFunction> functions;
bool scrolling;
bool isScrolling;
bool scrollingStarted;
cFunction *scrollFunc;
cList<cAnimation> blinkers;
list<cBlinker*> blinkers;
bool blinking;
void InitFunctions(void);
void CreatePixmap(cRect drawPort = cRect::Null);
@ -105,14 +111,20 @@ public:
int GetWidth(void) { return attribs->Width(); };
void Close(void);
void Clear(bool forceClearBackground = false);
void ClearWithoutIndicators(void);
void Hide(void);
void Show(void);
void Render(void);
bool Execute(void);
bool IsIndicatorArea(void) { return attribs->IndicatorArea(); };
void SetTransparency(int transparency, bool absolute = false);
void SetIndicatorTransparency(int transparency);
void SetIndicatorPosition(cPoint &pos);
cRect CoveringArea(void);
//Scrollable
bool Scrolling(void);
void SetScrollingStarted(void) { scrollingStarted = true; };
bool ScrollingStarted(void) { return scrollingStarted; };
int ScrollWidth(void);
int ScrollHeight(void);
int ScrollDelay(void);
@ -135,7 +147,6 @@ public:
//Common
const char *Name(void) { return attribs->Name(); };
bool BackgroundArea(void) { return attribs->BackgroundArea(); };
void Flush(void);
void Debug(bool full = false);
};
@ -163,11 +174,14 @@ public:
void Cache(void);
void Close(void);
void Clear(bool forceClearBackground = false);
void ClearWithoutIndicators(void);
void Hide(void);
void Show(void);
void Render(void);
bool Execute(void);
void SetTransparency(int transparency, bool absolute = false);
void SetIndicatorTransparency(int transparency);
void SetIndicatorPosition(cPoint &pos);
void SetViewPort(cRect &vp);
void SetPosition(cPoint &pos, cPoint &ref);
cRect CoveringArea(void);

View File

@ -339,6 +339,14 @@ void cAttributes::SetDirection(int id, const char *val) {
attribs[id] = (int)direction;
}
void cAttributes::SetButton(int id, const char *val) {
eButtonType button = eButtonType::none;
if (!strcmp(val, "left"))
button = eButtonType::left;
else if (!strcmp(val, "right"))
button = eButtonType::right;
attribs[id] = (int)button;
}
/***************************************************************************
* Private Functions
***************************************************************************/

View File

@ -46,6 +46,7 @@ protected:
void SetOrientation(int id, const char *val);
void SetDirection(int id, const char *val);
void SetAlign(int id, const char *val);
void SetButton(int id, const char *val);
public:
cAttributes(int numAttributes);
cAttributes(const cAttributes &other);

View File

@ -126,15 +126,18 @@ void cViewAttribs::SetOrientationDynamic(int id, const char *val) {
***************************************************************************/
cViewElementAttribs::cViewElementAttribs(int numAttributes) : cAttributes(numAttributes) {
name = NULL;
clearOnDisplay = NULL;
SetAttributesDefs();
}
cViewElementAttribs::cViewElementAttribs(const cViewElementAttribs &other) : cAttributes(other) {
name = NULL;
clearOnDisplay = NULL;
}
cViewElementAttribs::~cViewElementAttribs(void) {
free(name);
free(clearOnDisplay);
}
void cViewElementAttribs::Set(vector<stringpair> &attributes) {
@ -158,6 +161,8 @@ void cViewElementAttribs::Set(vector<stringpair> &attributes) {
SetOrientation(id, attVal);
} else if (IdEqual(id, (int)eViewElementAttribs::name)) {
name = strdup(attVal);
} else if (IdEqual(id, (int)eViewElementAttribs::clearondisplay)) {
clearOnDisplay = strdup(attVal);
} else {
attribCtors[id] = new cNumericExpr(attVal);
if (id == (int)eViewElementAttribs::starty + (int)eCommonAttribs::count) {
@ -178,6 +183,7 @@ void cViewElementAttribs::SetAttributesDefs(void) {
attribIDs.insert(pair<string, int>("orientation", (int)eViewElementAttribs::orientation));
attribIDs.insert(pair<string, int>("mode", (int)eViewElementAttribs::mode));
attribIDs.insert(pair<string, int>("name", (int)eViewElementAttribs::name));
attribIDs.insert(pair<string, int>("clearondisplay", (int)eViewElementAttribs::clearondisplay));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::delay, "delay"));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::fadetime, "fadetime"));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::shifttime, "shifttime"));
@ -188,6 +194,7 @@ void cViewElementAttribs::SetAttributesDefs(void) {
attribNames.insert(pair<int, string>((int)eViewElementAttribs::orientation, "orientation"));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::mode, "mode"));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::name, "name"));
attribNames.insert(pair<int, string>((int)eViewElementAttribs::clearondisplay, "clearondisplay"));
}
eOrientation cViewElementAttribs::Orientation(void) {
@ -233,6 +240,12 @@ void cViewListAttribs::Set(vector<stringpair> &attributes) {
determinateFont = strdup(attVal);
} else if (IdEqual(id, (int)eViewListAttribs::orientation)) {
SetOrientation(id, attVal);
} else if (IdEqual(id, (int)eViewListAttribs::shifttype)) {
SetShiftType(id, attVal);
} else if (IdEqual(id, (int)eViewListAttribs::shiftmode)) {
SetShiftMode(id, attVal);
} else if (IdEqual(id, (int)eViewListAttribs::button)) {
SetButton(id, attVal);
} else {
attribCtors[id] = new cNumericExpr(attVal);
}
@ -271,13 +284,27 @@ void cViewListAttribs::SetAttributesDefs(void) {
attribIDs.insert(pair<string, int>("determinatefont", (int)eViewListAttribs::determinatefont));
attribIDs.insert(pair<string, int>("numlistelements", (int)eViewListAttribs::numlistelements));
attribIDs.insert(pair<string, int>("orientation", (int)eViewListAttribs::orientation));
attribIDs.insert(pair<string, int>("fadetime", (int)eViewListAttribs::fadetime));
attribIDs.insert(pair<string, int>("shifttime", (int)eViewListAttribs::shifttime));
attribIDs.insert(pair<string, int>("shifttype", (int)eViewListAttribs::shifttype));
attribIDs.insert(pair<string, int>("shiftmode", (int)eViewListAttribs::shiftmode));
attribIDs.insert(pair<string, int>("startx", (int)eViewListAttribs::startx));
attribIDs.insert(pair<string, int>("starty", (int)eViewListAttribs::starty));
attribIDs.insert(pair<string, int>("condition", (int)eViewListAttribs::condition));
attribIDs.insert(pair<string, int>("button", (int)eViewListAttribs::button));
attribNames.insert(pair<int, string>((int)eViewListAttribs::align, "align"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::menuitemwidth, "menuitemwidth"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::determinatefont, "determinatefont"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::numlistelements, "numlistelements"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::orientation, "orientation"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::fadetime, "fadetime"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::shifttime, "shifttime"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::shifttype, "shifttype"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::shiftmode, "shiftmode"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::startx, "startx"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::starty, "starty"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::condition, "condition"));
attribNames.insert(pair<int, string>((int)eViewListAttribs::button, "button"));
}
void cViewListAttribs::Debug(void) {
@ -332,6 +359,8 @@ void cAreaAttribs::Set(vector<stringpair> &attributes) {
SetScrollSpeed(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::background)) {
SetBool(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::indicator)) {
SetBool(id, attVal);
} else if (IdEqual(id, (int)eAreaAttribs::name)) {
name = new cTextExpr(attVal);
} else {
@ -354,6 +383,13 @@ bool cAreaAttribs::BackgroundArea(void) {
return false;
}
bool cAreaAttribs::IndicatorArea(void) {
int isIndicator = GetValue((int)eAreaAttribs::indicator);
if (isIndicator == 1)
return true;
return false;
}
void cAreaAttribs::CheckDynamic(void) {
for (int i = (int)eCommonAttribs::x; i <= (int)eCommonAttribs::height; ++i ) {
if (attribCtors[i] && attribCtors[i]->Dynamic()) {
@ -378,6 +414,7 @@ void cAreaAttribs::SetAttributesDefs(void) {
attribIDs.insert(pair<string, int>("scrollspeed", (int)eAreaAttribs::scrollspeed));
attribIDs.insert(pair<string, int>("delay", (int)eAreaAttribs::delay));
attribIDs.insert(pair<string, int>("background", (int)eAreaAttribs::background));
attribIDs.insert(pair<string, int>("indicator", (int)eAreaAttribs::indicator));
attribIDs.insert(pair<string, int>("name", (int)eAreaAttribs::name));
attribIDs.insert(pair<string, int>("scrollheight", (int)eAreaAttribs::scrollheight));
attribNames.insert(pair<int, string>((int)eAreaAttribs::layer, "layer"));

View File

@ -30,6 +30,7 @@ public:
class cViewElementAttribs : public cAttributes {
private:
char *name;
char *clearOnDisplay;
void SetAttributesDefs(void);
public:
cViewElementAttribs(int numAttributes);
@ -45,6 +46,7 @@ public:
int ShiftType(void) { return GetValue((int)eViewElementAttribs::shifttype); };
int ShiftMode(void) { return GetValue((int)eViewElementAttribs::shiftmode); };
const char *Name(void) { return name; };
const char *ClearOnDisplay(void) { return clearOnDisplay; };
void Debug(void);
};
/******************************************************************
@ -63,6 +65,12 @@ public:
const char *DeterminateFont(void);
eAlign Align(void);
eOrientation Orientation(void);
int FadeTime(void) { return GetValue((int)eViewListAttribs::fadetime); };
int ShiftTime(void) { return GetValue((int)eViewListAttribs::shifttime); };
cPoint ShiftStartpoint(void) { return cPoint(GetValue((int)eViewListAttribs::startx), GetValue((int)eViewListAttribs::starty)); };
int ShiftType(void) { return GetValue((int)eViewListAttribs::shifttype); };
int ShiftMode(void) { return GetValue((int)eViewListAttribs::shiftmode); };
eButtonType Button(void) { return (eButtonType)GetValue((int)eViewListAttribs::button); }
void Debug(void);
};
/******************************************************************
@ -88,6 +96,7 @@ public:
int Layer(void);
int ScrollStep(void) { return GetValue((int)eAreaAttribs::scrollheight); };
bool BackgroundArea(void);
bool IndicatorArea(void);
const char *Name(void);
void CheckDynamic(void);
bool Dynamic(void) {return dynamic; };

View File

@ -83,13 +83,13 @@ cCond::cCond(const cCond &other) {
compareStrValue = strdup(other.compareStrValue);
}
cCond::~cCond(void) {
free(expr);
cCond::~cCond(void) {
free(expr);
free(compareStrValue);
}
void cCond::Debug(void) {
esyslog("skindesigner: cond %s, operation %s, type %d", expr,
esyslog("skindesigner: cond %s, operation %s, type %d", expr,
(operation == eCondOp::tAnd) ? "++" : "||",
(int)type);
if (constant)
@ -138,15 +138,15 @@ bool cCondition::True(void) {
for (cCond *c = conds.First(); c; c = conds.Next(c)) {
bool condTrue = true;
//evaluate condition
if (c->constant)
if (c->constant)
{
condTrue = c->isTrue;
}
else if (c->type == eCondType::token)
}
else if (c->type == eCondType::token)
{
if (c->tokenType == eCondTokenType::inttoken) {
int tokenVal = tokenContainer->IntToken(c->tokenIndex);
condTrue = (tokenVal > 0) ? true : false;
condTrue = (tokenVal > 0) ? true : false;
} else if (c->tokenType == eCondTokenType::stringtoken) {
char *tokenVal = tokenContainer->StringToken(c->tokenIndex);
if (tokenVal)
@ -159,8 +159,8 @@ bool cCondition::True(void) {
}
}
}
else if (c->type == eCondType::negtoken)
}
else if (c->type == eCondType::negtoken)
{
if (c->tokenType == eCondTokenType::inttoken) {
int tokenVal = tokenContainer->IntToken(c->tokenIndex);
@ -177,7 +177,7 @@ bool cCondition::True(void) {
}
}
}
else if (c->type == eCondType::lowerInt || c->type == eCondType::equalInt || c->type == eCondType::greaterInt)
else if (c->type == eCondType::lowerInt || c->type == eCondType::equalInt || c->type == eCondType::notequalInt || c->type == eCondType::greaterInt)
{
if (c->tokenType == eCondTokenType::inttoken) {
int tokenVal = tokenContainer->IntToken(c->tokenIndex);
@ -185,6 +185,8 @@ bool cCondition::True(void) {
condTrue = (tokenVal < c->compareValue) ? true : false;
else if (c->type == eCondType::equalInt)
condTrue = (tokenVal == c->compareValue) ? true : false;
else if (c->type == eCondType::notequalInt)
condTrue = (tokenVal != c->compareValue) ? true : false;
else if (c->type == eCondType::greaterInt)
condTrue = (tokenVal > c->compareValue) ? true : false;
} else if (c->tokenType == eCondTokenType::stringtoken) {
@ -195,6 +197,8 @@ bool cCondition::True(void) {
condTrue = (intVal < c->compareValue) ? true : false;
else if (c->type == eCondType::equalInt)
condTrue = (intVal == c->compareValue) ? true : false;
else if (c->type == eCondType::notequalInt)
condTrue = (intVal != c->compareValue) ? true : false;
else if (c->type == eCondType::greaterInt)
condTrue = (intVal > c->compareValue) ? true : false;
}
@ -207,13 +211,15 @@ bool cCondition::True(void) {
condTrue = (intVal < c->compareValue) ? true : false;
else if (c->type == eCondType::equalInt)
condTrue = (intVal == c->compareValue) ? true : false;
else if (c->type == eCondType::notequalInt)
condTrue = (intVal != c->compareValue) ? true : false;
else if (c->type == eCondType::greaterInt)
condTrue = (intVal > c->compareValue) ? true : false;
}
}
}
}
else if (c->type == eCondType::isset || c->type == eCondType::empty)
else if (c->type == eCondType::isset || c->type == eCondType::empty)
{
if (c->tokenType == eCondTokenType::stringtoken) {
char *tokenVal = tokenContainer->StringToken(c->tokenIndex);
@ -245,7 +251,7 @@ bool cCondition::True(void) {
}
}
}
else if (c->type == eCondType::equalString || c->type == eCondType::notEqualString || c->type == eCondType::contains || c->type == eCondType::notContains)
else if (c->type == eCondType::equalString || c->type == eCondType::notEqualString || c->type == eCondType::contains || c->type == eCondType::notContains)
{
if (c->tokenType == eCondTokenType::stringtoken) {
char *tokenVal = tokenContainer->StringToken(c->tokenIndex);
@ -278,7 +284,7 @@ bool cCondition::True(void) {
if (c->operation == eCondOp::tAnd) {
ok = ok && condTrue;
} else if (c->operation == eCondOp::tOr) {
ok = ok || condTrue;
ok = ok || condTrue;
}
}
return ok;
@ -308,6 +314,8 @@ void cCondition::Tokenize(void) {
type = eCondType::lowerInt;
} else if (startswith(cond, "eq({") && endswith(cond, ")")) {
type = eCondType::equalInt;
} else if (startswith(cond, "noteq({") && endswith(cond, ")")) {
type = eCondType::notequalInt;
} else if (startswith(cond, "gt({") && endswith(cond, ")")) {
type = eCondType::greaterInt;
} else if (startswith(cond, "isset{") && endswith(cond, "}")) {
@ -349,6 +357,7 @@ void cCondition::PrepareTokens(void) {
break;
case eCondType::lowerInt:
case eCondType::equalInt:
case eCondType::notequalInt:
case eCondType::greaterInt:
SetIntegerCond(c);
break;
@ -409,6 +418,8 @@ void cCondition::SetIntegerCond(cCond *c) {
c->isTrue = true;
else if (c->type == eCondType::equalInt && result == c->compareValue)
c->isTrue = true;
else if (c->type == eCondType::notequalInt && result != c->compareValue)
c->isTrue = true;
else if (c->type == eCondType::greaterInt && result > c->compareValue)
c->isTrue = true;
return;
@ -459,8 +470,8 @@ void cCondition::SetTokenIndex(cCond *c, const char *token) {
/******************************************************************
* cSummand
******************************************************************/
cSummand::cSummand(const char *summand) {
this->summand = strdup(summand);
cSummand::cSummand(const char *summand) {
this->summand = strdup(summand);
}
cSummand::cSummand(const cSummand &other) {
@ -474,7 +485,7 @@ cSummand::cSummand(const cSummand &other) {
}
cSummand::~cSummand(void) {
free(summand);
free(summand);
}
void cSummand::Debug(void) {
@ -553,7 +564,7 @@ bool cNumericExpr::CacheStatic(void) {
value = atoi(expr);
return true;
}
//check if expression is a percent expression
if (PercentValue(expr)) {
return true;
@ -562,9 +573,7 @@ bool cNumericExpr::CacheStatic(void) {
expr = ReplacePercentValue(expr);
//replace {areawidth} and {areaheight}
if (container->Width() >= 0) {
//esyslog("skindesigner: replacing areawidth %s", expr);
expr = ReplaceTokens(expr, "{areawidth}", container->Width());
//esyslog("skindesigner: replaced areawidth %s", expr);
}
if (container->Height() >= 0)
expr = ReplaceTokens(expr, "{areaheight}", container->Height());
@ -667,7 +676,7 @@ int cNumericExpr::Calculate(void) {
if (f->multiplication)
factor *= fac;
else if (fac)
factor /= fac;
factor /= fac;
}
if (s->positive)
result += factor;
@ -713,19 +722,19 @@ bool cNumericExpr::IsNumericExpression(const char *e) {
else
return false;
}
return true;
return true;
}
bool cNumericExpr::PercentValue(const char *e) {
if (!e)
return e;
const char *hit = strchr(e, '%');
if (!hit)
return false;
char buffer[20] = "";
if (strlen(e) > 20)
return false;
strncpy(buffer, e, strlen(e)-1);
buffer[strlen(e)-1] = '\0';
int val = atoi(buffer);
int val;
int r = sscanf(e, "%d%%", &val); // use sscanf to retrieve %-value to avoid -Wstringop-overflow
if (r != 1)
return false; // sscanf parsing problem
bool ok = false;
if (horizontal && container->Width() > 0) {
value = container->Width() * val / 100;
@ -738,22 +747,22 @@ bool cNumericExpr::PercentValue(const char *e) {
}
char *cNumericExpr::ReplacePercentValue(char *e) {
if (!e)
return e;
const char *hit = strchr(e, '%');
if (!hit)
return e;
char buffer[20] = "";
if (strlen(e) > 20)
return e;
strncpy(buffer, e, strlen(e)-1);
buffer[strlen(e)-1] = '\0';
int val = atoi(buffer);
int val;
int r = sscanf(e, "%d%%", &val); // use sscanf to retrieve %-value to avoid -Wstringop-overflow
if (r != 1)
return e; // sscanf parsing problem
double percentVal = (double)val/100.0f;
char replacement[50] = "";
if (horizontal) {
sprintf(replacement, "%.5f*{areawidth}", percentVal);
snprintf(replacement, sizeof(replacement), "%.5f*{areawidth}", percentVal);
} else {
sprintf(replacement, "%.5f*{areaheight}", percentVal);
snprintf(replacement, sizeof(replacement), "%.5f*{areaheight}", percentVal);
}
int len = strlen(replacement) + 1;
@ -765,16 +774,19 @@ char *cNumericExpr::ReplacePercentValue(char *e) {
}
char *cNumericExpr::ReplaceToken(char *e, const char* token, int val) {
if (!e)
return e;
char *tokenStart = strstr(e, token);
if (!tokenStart) {
return e;
}
char buffer[20] = "";
sprintf(buffer, "%d", val);
snprintf(buffer, sizeof(buffer), "%d", val);
size_t newSize = strlen(e) - strlen(token) + strlen(buffer) + 1;
char *replaced = (char*)malloc(newSize);
memset(replaced, 0, newSize);
size_t beginning = strlen(e) - strlen(tokenStart);
if (beginning >= newSize) beginning = newSize - 1; // will never happen but avoid -Wstringop-overflow
if (beginning > 0)
strncpy(replaced, e, beginning);
strcat(replaced, buffer);
@ -879,7 +891,7 @@ void cNumericExpr::CreateFactors(void) {
f->constValue = EvaluateExpressionDouble(sum);
s->factors.Add(f);
free(sum);
continue;
continue;
}
bool multiplication = true;
char *fac = strtok(sum, delimiterFac);
@ -897,7 +909,7 @@ void cNumericExpr::CreateFactors(void) {
} else if (SetReferenceFactor(f, fac)) {
f->multiplication = multiplication;
s->factors.Add(f);
} else if (SetGeometryFactor(f, fac)) {
} else if (SetGeometryFactor(f, fac)) {
f->multiplication = multiplication;
s->factors.Add(f);
} else {
@ -952,7 +964,7 @@ bool cNumericExpr::SetReferenceFactor(cFactor *f, char *tokenName) {
f->type = eFactorType::widthref;
} else if (startswith(tokenName, "{height(") && endswith(tokenName, ")}")) {
start = 8;
f->type = eFactorType::heightref;
f->type = eFactorType::heightref;
}
if (start == 0)
@ -977,7 +989,7 @@ bool cNumericExpr::SetGeometryFactor(cFactor *f, char *tokenName) {
f->type = eFactorType::columnwidth;
ok = true;
} else if (!strcmp(tokenName, "{rowheight}")) {
f->type = eFactorType::rowheight;
f->type = eFactorType::rowheight;
ok = true;
}
return ok;
@ -998,7 +1010,7 @@ void cNumericExpr::ConsolidateSummand(void) {
s = constSummand;
}
}
}
}
}
void cNumericExpr::ConsolidateFactors(void) {
@ -1011,7 +1023,7 @@ void cNumericExpr::ConsolidateFactors(void) {
} else {
if (f->multiplication)
constFactor->constValue *= f->constValue;
else
else
constFactor->constValue /= f->constValue;
s->factors.Del(f);
f = constFactor;
@ -1033,7 +1045,7 @@ cColor::cColor(const char *expression) {
cColor::cColor(const cColor &other) {
globals = other.globals;
expr = strdup(other.expr);
value = other.value;
value = other.value;
}
cColor::~cColor(void) {
@ -1433,7 +1445,7 @@ bool cTextExpr::ParsePrintfToken(cTextToken *t) {
strncpy(buffer, startExpr+1, expLen);
buffer[expLen] = '\0';
t->printfExpr = strdup(buffer);
//find variables
char *startVar = strchr(t->constValue, ',');
if (!startVar)
@ -1516,7 +1528,7 @@ void cTextExpr::DeterminatePrintfToken(cTextToken *t) {
}
} else if (t->printfVarIndices[i].type == ePrintfVarType::looptoken && loopInfo && loopInfo->row >= 0) {
if (tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->printfVarIndices[i].index)) {
results.push_back(atoi(tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->printfVarIndices[i].index)));
results.push_back(atoi(tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->printfVarIndices[i].index)));
}
}
}
@ -1602,8 +1614,8 @@ char *cTextExpr::CopyTextPart(char *start, char *stop, bool incLastChar) {
} else {
//search end of text
char *p = start;
while (*p)
len++; p++;
while (*p) {
len++; p++; }
len++;
}
val = (char*)malloc(len+1);

View File

@ -32,6 +32,7 @@ enum class eCondType {
negtoken,
lowerInt,
equalInt,
notequalInt,
greaterInt,
isset,
empty,

File diff suppressed because it is too large Load Diff

View File

@ -421,6 +421,7 @@ void cFuncDrawText::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeig
} else if (horAlign == eAlign::center) {
x = x0 + (contWidth - TextWidth(funcText)) / 2;
}
if (x < 0) x = 0;
int contHeight = rowHeight > 0 ? rowHeight : container.Height();
int y = Y() + y0;
@ -449,7 +450,7 @@ int cFuncDrawText::FuncX(void) {
} else if (horAlign == eAlign::center) {
x = (container.Width() - TextWidth(funcText)) / 2;
}
return x;
return (x >= 0) ? x : 0 ;
}
int cFuncDrawText::FuncY(void) {
@ -1170,6 +1171,8 @@ void cFuncLoop::Set(vector<stringpair> &attributes) {
SetOrientation(id, attVal);
} else if (IdEqual(id, (int)eLoopAttribs::overflow)) {
SetOverflow(id, attVal);
} else if (IdEqual(id, (int)eLoopAttribs::valign)) {
SetAlign(id, attVal);
} else {
attribCtors[id] = new cNumericExpr(attVal);
}
@ -1228,11 +1231,15 @@ void cFuncLoop::Render(cPixmap *p, int x0, int y0, int cw, int rh) {
return;
}
int numRows = tokenContainer->NumLoops(loopIndex);
if (numRows < 1)
return;
int columnWidth = GetValue((int)eLoopAttribs::columnwidth);
int rowHeight = GetValue((int)eLoopAttribs::rowheight);
int maxItems = GetValue((int)eLoopAttribs::maxitems);
eOrientation orientation = (eOrientation)GetValue((int)eLoopAttribs::orientation);
eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow);
eAlign vAlign = (eAlign)GetValue((int)eLoopAttribs::valign);
int loopWidth = Width();
if (loopWidth <= 0)
loopWidth = container.Width();
@ -1248,6 +1255,22 @@ void cFuncLoop::Render(cPixmap *p, int x0, int y0, int cw, int rh) {
int loopY = Y();
int x = (loopX > 0) ? loopX : 0;
int y = (loopY > 0) ? loopY : 0;
//set y position for vertical loop with valign bottom
if (orientation == eOrientation::vertical && vAlign == eAlign::bottom) {
int actRowheight = (rowHeight > 0) ? rowHeight : RowHeight();
if (actRowheight > 0) {
float fTotalItems = (float)loopHeight / (float)actRowheight;
int totalItems = (int)fTotalItems;
if (fTotalItems - (float)totalItems > 0.5f)
totalItems++;
if (maxItems > 0 && maxItems < totalItems)
totalItems = maxItems;
if (numRows < totalItems)
y += (totalItems - numRows) * actRowheight;
}
}
for (int row = 0; row < numRows; ++row) {
if (maxItems > 0 && row >= maxItems) {
break;
@ -1300,13 +1323,16 @@ int cFuncLoop::FuncWidth(void) {
return 0;
}
int numLoops = tokenContainer->NumLoops(loopIndex);
if (numLoops < 1)
return 0;
int columnWidth = GetValue((int)eLoopAttribs::columnwidth);
if (columnWidth <=0)
columnWidth = ColumnWidth();
eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow);
if (overflow == eOverflowType::cut) {
int maxItems = GetValue((int)eLoopAttribs::maxitems);
numLoops = min(numLoops, maxItems);
numLoops = std::min(numLoops, maxItems);
}
if (numLoops > 0)
return numLoops * columnWidth;
@ -1321,6 +1347,9 @@ int cFuncLoop::FuncHeight(void) {
return 0;
}
int numLoops = tokenContainer->NumLoops(loopIndex);
if (numLoops < 1)
return 0;
int rowHeight = GetValue((int)eLoopAttribs::rowheight);
if (rowHeight <=0)
rowHeight = RowHeight();
@ -1328,7 +1357,7 @@ int cFuncLoop::FuncHeight(void) {
eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow);
if (overflow == eOverflowType::cut) {
int maxItems = GetValue((int)eLoopAttribs::maxitems);
numLoops = min(numLoops, maxItems);
numLoops = std::min(numLoops, maxItems);
} else if (overflow == eOverflowType::wrap) {
int loopWidth = Width();
if (loopWidth <= 0)
@ -1362,12 +1391,14 @@ void cFuncLoop::SetAttributesDefs(void) {
attribIDs.insert(pair<string, int>("rowheight", (int)eLoopAttribs::rowheight));
attribIDs.insert(pair<string, int>("name", (int)eLoopAttribs::name));
attribIDs.insert(pair<string, int>("orientation", (int)eLoopAttribs::orientation));
attribIDs.insert(pair<string, int>("valign", (int)eLoopAttribs::valign));
attribIDs.insert(pair<string, int>("overflow", (int)eLoopAttribs::overflow));
attribIDs.insert(pair<string, int>("maxitems", (int)eLoopAttribs::maxitems));
attribNames.insert(pair<int, string>((int)eLoopAttribs::columnwidth, "columnwidth"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::rowheight, "rowheight"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::name, "name"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::orientation, "orientation"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::valign, "valign"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::overflow, "overflow"));
attribNames.insert(pair<int, string>((int)eLoopAttribs::maxitems, "maxitems"));
}

View File

@ -187,6 +187,7 @@ public:
void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0);
int FuncWidth(void);
int FuncHeight(void);
int Valign(void) { return GetValue((int)eLoopAttribs::valign); };
void Debug(void);
};

File diff suppressed because it is too large Load Diff

View File

@ -8,28 +8,45 @@
/******************************************************************
* cListElement
******************************************************************/
class cListElement : public cViewElement {
class cListElement : public cViewElement , public cListShiftable {
protected:
eMenuCategory menuCat;
eOrientation orientation;
int num;
bool current;
bool wasCurrent;
bool selectable;
bool selectedFromTop;
bool suppressAnimation;
cListShifter *listShifter;
cViewElement *currentElement;
char *ParseSeparator(const char *text);
void StartListAnimation(void);
public:
cListElement(void);
cListElement(const cListElement &other);
virtual ~cListElement(void) {};
void SetMenuCategory(eMenuCategory menuCat) { this->menuCat = menuCat; };
void SetOrientation(eOrientation orientation) { this->orientation = orientation; };
void SetNumber(int number) { num = number; };
void SetCurrent(bool cur);
bool Current(void) { return current; };
bool WasCurrent(void) { return wasCurrent; };
void WakeCurrent(void);
void SetSelectable(bool sel) { selectable = sel; };
void SetSelectedFromTop(void) { selectedFromTop = true; };
void SetSelectedFromBottom(void) { selectedFromTop = false; };
void SetSuppressAnimation(bool suppress) { suppressAnimation = suppress; };
bool DoScroll(void) { return current; };
void Render(void);
virtual void RenderCurrent(void) { };
void Close(void);
virtual void Close(void);
int ListShiftTime(void) { return ShiftTime(); };
int ShiftDistance(void);
eOrientation ShiftOrientation(void);
void SetIndicatorPosition(cPoint &position);
void SetTransparency(int transparency, bool force = false);
void StopListAnimation(void);
virtual void Clear(bool forceClearBackground = false);
};
@ -42,10 +59,11 @@ protected:
int listY;
int listWidth;
int listHeight;
int listNum;
public:
cCurrentElement(void);
virtual ~cCurrentElement(void) {};
void SetListPosition(int x, int y, int width, int height);
void SetListPosition(int x, int y, int width, int height, int num);
void SetListTokens(skindesignerapi::cTokenContainer *tokenContainer);
};
@ -265,6 +283,8 @@ public:
void Set(const cRecording *recording, int level, int total, int New);
bool Parse(bool forced = true);
void RenderCurrent(void);
void Clear(bool forceClearBackground = false);
void Close(void);
};
/******************************************************************
@ -338,4 +358,35 @@ public:
bool Parse(bool forced = true);
};
/******************************************************************
* cLeChannelList
******************************************************************/
class cLeChannelList : public cListElement {
private:
const cChannel *channel;
public:
cLeChannelList(void);
cLeChannelList(const cLeChannelList &other);
virtual ~cLeChannelList(void);
void SetTokenContainer(void);
void Set(const cChannel *channel);
bool Parse(bool forced = true);
};
/******************************************************************
* cLeGroupList
******************************************************************/
class cLeGroupList : public cListElement {
private:
const char *group;
int numChannels;
public:
cLeGroupList(void);
cLeGroupList(const cLeGroupList &other);
virtual ~cLeGroupList(void);
void SetTokenContainer(void);
void Set(const char *group, int numChannels);
bool Parse(bool forced = true);
};
#endif //__LISTELEMENTS_H

View File

@ -2,7 +2,6 @@
cSdOsd::cSdOsd(void) {
osd = NULL;
flushLocked = false;
}
cSdOsd::~cSdOsd(void) {
@ -17,18 +16,6 @@ void cSdOsd::Unlock(void) {
mutex.Unlock();
}
void cSdOsd::LockFlush(void) {
Lock();
flushLocked = true;
Unlock();
}
void cSdOsd::UnlockFlush(void) {
Lock();
flushLocked = false;
Unlock();
}
bool cSdOsd::CreateOsd(int x, int y, int width, int height) {
cOsd *newOsd = cOsdProvider::NewOsd(cOsd::OsdLeft() + x, cOsd::OsdTop() + y);
if (newOsd) {
@ -64,6 +51,7 @@ void cSdOsd::DestroyPixmap(cPixmap *pix) {
}
void cSdOsd::Flush(void) {
if (osd && !flushLocked)
if (osd) {
osd->Flush();
}
}

View File

@ -8,14 +8,11 @@ class cSdOsd {
private:
cOsd *osd;
cMutex mutex;
bool flushLocked;
public:
cSdOsd(void);
virtual ~cSdOsd(void);
void Lock(void);
void Unlock(void);
void LockFlush(void);
void UnlockFlush(void);
bool CreateOsd(int x, int y, int width, int height);
void DeleteOsd(void);
cPixmap *CreatePixmap(int layer, cRect &viewPort, cRect &drawPort);

View File

@ -3,6 +3,8 @@
// --- cView -------------------------------------------------------------
cAnimator* cView::animator = NULL;
cView::cView(void) {
globals = NULL;
viewName = NULL;
@ -10,8 +12,6 @@ cView::cView(void) {
numViewElements = 0;
viewElements = NULL;
viewElementsHorizontal = NULL;
fader = NULL;
shifter = NULL;
shifting = false;
currentTvFrame = NULL;
newTvFrame = NULL;
@ -29,8 +29,8 @@ cView::~cView() {
}
delete attribs;
free(viewName);
delete fader;
delete shifter;
delete animator;
animator = NULL;
shifting = false;
sdOsd.DeleteOsd();
}
@ -141,6 +141,12 @@ bool cView::ValidViewElement(const char *viewElement) {
bool cView::ValidViewList(const char *viewList) {
if (!strcmp(viewList, "menuitems"))
return true;
else if (!strcmp(viewList, "channellist"))
return true;
else if (!strcmp(viewList, "grouplist"))
return true;
else if (!strcmp(viewList, "groupchannellist"))
return true;
return false;
}
@ -160,17 +166,15 @@ void cView::PreCache(void) {
for (int i=0; i < numViewElements; i++) {
if (!viewElements[i])
continue;
if (FadeTime() > 0 || ShiftTime() > 0)
viewElements[i]->SetAnimatedView();
viewElements[i]->SetContainer(contX, contY, attribs->Width(), attribs->Height());
viewElements[i]->Cache();
if (const char *clearOnDisplay = viewElements[i]->ClearOnDisplay())
SetClearOnDisplay(i, clearOnDisplay);
}
if (viewElementsHorizontal) {
for (int i=0; i < numViewElements; i++) {
if (!viewElementsHorizontal[i])
continue;
if (FadeTime() > 0 || ShiftTime() > 0)
viewElementsHorizontal[i]->SetAnimatedView();
viewElementsHorizontal[i]->SetContainer(contX, contY, attribs->Width(), attribs->Height());
viewElementsHorizontal[i]->Cache();
}
@ -199,11 +203,27 @@ void cView::PreCache(void) {
SetViewElementObjects();
}
void cView::AddAnimation(cAnimation *animation, bool startAnimation) {
if (!animator)
return;
animator->AddAnimation(animation, startAnimation);
}
void cView::RemoveAnimation(cAnimation *animation) {
if (!animator)
return;
animator->RemoveAnimation(animation);
}
bool cView::Init(void) {
int osdX = attribs->X();
int osdY = attribs->Y();
int osdWidth = attribs->Width();
int osdHeight = attribs->Height();
if (!animator)
animator = new cAnimator(&sdOsd);
else
esyslog("skindesigner: ERROR: animator already exists");
return sdOsd.CreateOsd(osdX, osdY, osdWidth, osdHeight);
}
@ -213,6 +233,13 @@ void cView::Clear(int ve, bool forceClearBackground) {
viewElements[ve]->Clear(forceClearBackground);
}
void cView::SetDirty(int ve) {
if (!viewElements[ve])
return;
viewElements[ve]->SetDirty();
viewElements[ve]->SetRestartAnimation();
}
void cView::Render(int ve, bool force) {
if (!viewElements[ve])
return;
@ -220,24 +247,30 @@ void cView::Render(int ve, bool force) {
viewElements[ve]->Render();
}
void cView::Hide(int ve) {
if (!viewElements[ve])
return;
viewElements[ve]->Hide();
}
void cView::Show(int ve) {
if (!viewElements[ve])
return;
viewElements[ve]->Show();
}
void cView::SetViewelementsAnimOut(void) {
for (int i=0; i< numViewElements; i++)
if (viewElements[i])
viewElements[i]->SetAnimOut();
}
void cView::Close(void) {
delete fader;
fader = NULL;
delete shifter;
shifter = NULL;
if (initFinished && ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint end = ShiftStart(shiftbox);
shifter = new cAnimation((cShiftable*)this, end, ref, false);
shifter->Shift();
delete shifter;
shifter = NULL;
} else if (initFinished && FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
if (animator) {
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
}
UnScaleTv();
ClearVariables();
@ -246,7 +279,7 @@ void cView::Close(void) {
continue;
viewElements[i]->Close();
}
sdOsd.Flush();
// sdOsd.Flush();
sdOsd.DeleteOsd();
}
@ -267,7 +300,16 @@ int cView::ShiftTime(void) {
}
int cView::ShiftMode(void) {
return attribs->ShiftMode();
int mode = attribs->ShiftMode();
if (mode < 0) mode = 0;
return mode;
}
void cView::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cView::SetPosition(cPoint &position, cPoint &reference, bool force) {
@ -283,9 +325,6 @@ void cView::Flush(void) {
init = false;
StartAnimation();
menuInit = true;
//LockFlush was set at startup of view to avoid display
//of not positioned pixmaps for shifting and fading
sdOsd.UnlockFlush();
}
if (menuInit) {
ScaleTv();
@ -311,7 +350,6 @@ void cView::Debug(void) {
*******************************************************************/
void cView::ClearVariables(void) {
init = true;
initFinished = false;
newTvFrame = NULL;
currentTvFrame = NULL;
menuInit = false;
@ -325,22 +363,19 @@ int cView::ViewElementId(const char *name) {
}
void cView::StartAnimation(void) {
if (ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint start = ShiftStart(shiftbox);
SetPosition(start, ref);
shifter = new cAnimation((cShiftable*)this, start, ref, true);
shifter->Start();
} else if (FadeTime() > 0) {
if (fader)
return;
SetTransparency(100);
sdOsd.Flush();
fader = new cAnimation((cFadable*)this, true);
fader->Start();
if (viewId != eViewType::DisplayMenu &&
viewId != eViewType::DisplayPlugin) {
if (ShiftTime() > 0) {
cShifter *shifter = new cShifter((cShiftable*)this);
shifter->SetPersistent();
cView::AddAnimation(shifter);
} else if (FadeTime() > 0) {
cFader *fader = new cFader((cFadable*)this);
fader->SetPersistent();
cView::AddAnimation(fader);
}
}
initFinished = true;
animator->Start();
}
void cView::WakeViewElements(void) {
@ -428,3 +463,20 @@ void cView::DoScaleTv(const cRect *frame) {
}
}
}
void cView::SetClearOnDisplay(int ve, const char *clearOnDisplay) {
if (!strcmp(clearOnDisplay, "all")) {
viewElements[ve]->SetClearAll();
return;
}
vector<int> clearVEs;
for (map<string,int>::iterator it = viewElementNames.begin(); it != viewElementNames.end(); it++) {
string name = it->first;
int id = it->second;
if (strstr(clearOnDisplay, name.c_str())) {
clearVEs.push_back(id);
}
}
viewElements[ve]->SetClearOnDisplay(clearVEs);
}

View File

@ -26,12 +26,13 @@ using namespace std;
class cView : public cFadable, public cShiftable {
private:
void DoScaleTv(const cRect *frame);
void SetClearOnDisplay(int ve, const char *clearOnDisplay);
protected:
cSdOsd sdOsd;
static cAnimator *animator;
cViewAttribs *attribs;
cRect container;
bool init;
bool initFinished;
eViewType viewId;
cGlobals *globals;
char *viewName;
@ -39,8 +40,6 @@ protected:
cViewElement **viewElements;
cViewElement **viewElementsHorizontal;
map<string,int> viewElementNames;
cAnimation *fader;
cAnimation *shifter;
bool shifting;
cRect tvFrame;
cRect *currentTvFrame;
@ -73,21 +72,27 @@ public:
virtual const cFont *GetTextAreaFont(void) { return NULL; };
virtual int GetTextAreaWidth(void) { return 0; };
virtual int GetListWidth(void) { return 0; };
static void AddAnimation(cAnimation *animation, bool startAnimation = true);
static void RemoveAnimation(cAnimation *animation);
//View API
virtual bool Init(void);
void Clear(int ve, bool forceClearBackground = false);
void SetDirty(int ve);
void Render(int ve, bool force = false);
void Hide(int ve);
void Show(int ve);
virtual void Close(void);
virtual void Flush(void);
virtual void Debug(void);
bool Detached(void) { return false; };
int Delay(void) { return 0; };
void SetViewelementsAnimOut(void);
//Fadable
int Delay(void) { return 0; };
int FadeTime(void);
virtual void SetTransparency(int transparency, bool force = false);
//Shiftable
int ShiftTime(void);
int ShiftMode(void);
void ShiftPositions(cPoint *start, cPoint *end);
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { shifting = true; };
void SetEndShifting(void) { shifting = false; };

View File

@ -353,13 +353,15 @@ bool cViewDetailEpg::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::year, sStartTime->tm_year + 1900);
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::daynumeric, sStartTime->tm_mday);
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::month, sStartTime->tm_mon+1);
const cChannel* channel = NULL;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
{
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
channel = Channels->GetByChannelID(event->ChannelID());
}
#else
cChannels* channels = &Channels;
channel = Channels.GetByChannelID(event->ChannelID());
#endif
const cChannel *channel = channels->GetByChannelID(event->ChannelID());
if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedEpgST::channelname, channel->Name());
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::channelnumber, channel->Number());
@ -385,7 +387,10 @@ bool cViewDetailEpg::Parse(bool forced) {
tokenContainer->AddStringToken((int)eDmDetailedEpgST::vps, *event->GetVpsString());
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns = LoadReruns();
int numReruns = NumReruns(reruns);
int numReruns = 0;
if (reruns && reruns->Count() > 0)
numReruns = reruns->Count();
vector<int> loopInfo;
//num reruns
loopInfo.push_back(numReruns);
@ -395,7 +400,7 @@ bool cViewDetailEpg::Parse(bool forced) {
loopInfo.push_back(numActors);
tokenContainer->CreateLoopTokenContainer(&loopInfo);
if (numReruns > 0) {
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::hasreruns, 1);
tokenContainer->AddIntToken((int)eDmDetailedEpgIT::hasreruns, numReruns);
SetReruns(reruns);
}
if (scrapInfoAvailable) {
@ -411,88 +416,75 @@ cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *cViewDetailEpg::LoadR
if (!epgSearchPlugin)
return NULL;
if (isempty(event->Title()))
if (!event || isempty(event->Title()))
return NULL;
Epgsearch_searchresults_v1_0 data;
data.query = (char*)event->Title();
std::string strQuery = event->Title();
if (config.useSubtitleRerun && !isempty(event->ShortText())) {
strQuery += "~";
strQuery += event->ShortText();
}
data.query = (char *)strQuery.c_str();
data.mode = 0;
data.channelNr = 0;
data.useTitle = true;
data.useSubTitle = true;
data.useDescription = false;
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *result = NULL;
if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data))
result = data.pResultList;
return result;
}
int cViewDetailEpg::NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) {
if (!reruns || reruns->Count() < 2)
return 0;
int maxNumReruns = config.rerunAmount;
int rerunDistance = config.rerunDistance * 3600;
int rerunMaxChannel = config.rerunMaxChannel;
int i = 0;
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
time_t eventStart = event->StartTime();
time_t rerunStart = r->event->StartTime();
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns = NULL;
if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) {
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *result = data.pResultList;
if (result) {
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = result->First(); r && i < maxNumReruns; r = result->Next(r)) {
time_t eventStart = event->StartTime();
time_t rerunStart = r->event->StartTime();
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(r->event->ChannelID(), true, true);
#else
cChannels* channels = &Channels;
const cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
#endif
const cChannel *channel = channels->GetByChannelID(r->event->ChannelID(), true, true);
//check for identical event
if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
continue;
//check for timely distance
if (rerunDistance > 0)
if (rerunStart - eventStart < rerunDistance)
continue;
//check for maxchannel
if (rerunMaxChannel > 0)
if (channel && channel->Number() > rerunMaxChannel)
continue;
i++;
//check for identical event
if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
continue;
//check for timely distance
if (rerunDistance > 0)
if (rerunStart - eventStart < rerunDistance)
continue;
//check for maxchannel
if (rerunMaxChannel > 0)
if (channel && channel->Number() > rerunMaxChannel)
continue;
if (!reruns) reruns = new cList<Epgsearch_searchresults_v1_0::cServiceSearchResult>;
reruns->Add(r);
i++;
}
}
}
return i;
return reruns;
}
void cViewDetailEpg::SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns) {
if (!reruns || reruns->Count() < 2)
if (!reruns || reruns->Count() < 1)
return;
int maxNumReruns = config.rerunAmount;
int rerunDistance = config.rerunDistance * 3600;
int rerunMaxChannel = config.rerunMaxChannel;
int i = 0;
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) {
time_t eventStart = event->StartTime();
time_t rerunStart = r->event->StartTime();
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r; r = reruns->Next(r)) {
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
const cChannel *channel = Channels->GetByChannelID(r->event->ChannelID(), true, true);
#else
cChannels* channels = &Channels;
const cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
#endif
const cChannel *channel = channels->GetByChannelID(r->event->ChannelID(), true, true);
//check for identical event
if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart))
continue;
//check for timely distance
if (rerunDistance > 0)
if (rerunStart - eventStart < rerunDistance)
continue;
//check for maxchannel
if (rerunMaxChannel > 0)
if (channel && channel->Number() > rerunMaxChannel)
continue;
tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::title, r->event->Title());
tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::shorttext, r->event->ShortText());
tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::start, *(r->event->GetTimeString()));
@ -511,6 +503,8 @@ void cViewDetailEpg::SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearc
tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, "");
tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, "");
}
if (r == reruns->Last())
break;
i++;
}
}
@ -609,6 +603,13 @@ void cViewDetailRec::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{recimg1avaialble}", (int)eDmDetailedRecIT::recimg1avaialble);
tokenContainer->DefineIntToken("{recimg2avaialble}", (int)eDmDetailedRecIT::recimg2avaialble);
tokenContainer->DefineIntToken("{recimg3avaialble}", (int)eDmDetailedRecIT::recimg3avaialble);
tokenContainer->DefineIntToken("{fps}", (int)eDmDetailedRecIT::framesPerSecond);
tokenContainer->DefineIntToken("{isHD}", (int)eDmDetailedRecIT::isHD);
tokenContainer->DefineIntToken("{isUHD}", (int)eDmDetailedRecIT::isUHD);
tokenContainer->DefineIntToken("{isRadio}", (int)eDmDetailedRecIT::isRadio);
tokenContainer->DefineIntToken("{isRecording}", (int)eDmDetailedRecIT::isRecording);
tokenContainer->DefineIntToken("{isInUse}", (int)eDmDetailedRecIT::isInUse);
tokenContainer->DefineIntToken("{errors}", (int)eDmDetailedRecIT::errors);
tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie);
tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget);
tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue);
@ -672,6 +673,13 @@ bool cViewDetailRec::Parse(bool forced) {
tokenContainer->AddStringToken((int)eDmDetailedRecST::epgname, info->Title());
tokenContainer->AddStringToken((int)eDmDetailedRecST::shorttext, info->ShortText());
tokenContainer->AddStringToken((int)eDmDetailedRecST::description, info->Description());
tokenContainer->AddIntToken((int)eDmDetailedRecIT::framesPerSecond, info->FramesPerSecond());
int errors = -1;
// ENABLE_ERRORS is only used in VDR-2.5.4 if the coresponding patch is installed, so it can be ignored in other versions
#if (defined (APIVERSNUM) && (APIVERSNUM >= 20505)) || defined (ENABLE_ERRORS)
errors = info->Errors();
#endif
tokenContainer->AddIntToken((int)eDmDetailedRecIT::errors, errors);
const cEvent *event = info->GetEvent();
if (event) {
cString recDate = event->GetDateString();
@ -697,6 +705,11 @@ bool cViewDetailRec::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedRecIT::durationevent, duration);
tokenContainer->AddIntToken((int)eDmDetailedRecIT::durationeventhours, duration / 60);
tokenContainer->AddStringToken((int)eDmDetailedRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60));
tokenContainer->AddIntToken((int)eDmDetailedRecIT::isHD, RecordingIsHD(event, tChannelID::InvalidID)); // detect HD from 'info', no fallback to channelID
tokenContainer->AddIntToken((int)eDmDetailedRecIT::isUHD, RecordingIsUHD(event, tChannelID::InvalidID)); // detect UHD from 'info', no fallback to channelID
tokenContainer->AddIntToken((int)eDmDetailedRecIT::isRadio, RecordingIsRadio(event, info->FramesPerSecond())); // detect Radio from 'info' and FPS
tokenContainer->AddIntToken((int)eDmDetailedRecIT::isRecording, recording->IsInUse() & ruTimer);
tokenContainer->AddIntToken((int)eDmDetailedRecIT::isInUse, recording->IsInUse());
}
}
SetRecInfos();
@ -810,21 +823,25 @@ void cViewDetailRec::SetRecInfos(void) {
const cRecordingInfo *info = recording->Info();
if (info) {
if (info->ChannelName() && (strlen(info->ChannelName()) > 0)) {
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, info->ChannelName());
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, info->ChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedRecIT::recchannelnumber, 0); // cannot be provided, for backward compatibility only
} else {
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(info->ChannelID());
#else
cChannels* channels = &Channels;
const cChannel *channel = Channels.GetByChannelID(info->ChannelID());
#endif
const cChannel *channel = channels->GetByChannelID(info->ChannelID());
if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, *channel->GetChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedRecIT::recchannelnumber, channel->Number());
}
if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, *channel->GetChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedRecIT::recchannelnumber, channel->Number());
}
}
}
if (index) {
int nLastIndex = index->Last();
if (nLastIndex) {

View File

@ -44,7 +44,6 @@ protected:
int rerunsIndex;
int actorsIndex;
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *LoadReruns(void);
int NumReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns);
void SetReruns(cList<Epgsearch_searchresults_v1_0::cServiceSearchResult> *reruns);
void SetEpgPictures(int eventId);
public:
@ -112,4 +111,4 @@ public:
void Set(skindesignerapi::cTokenContainer *tk);
bool Parse(bool forced = false);
};
#endif //__VIEWDETAIL_H
#endif //__VIEWDETAIL_H

View File

@ -24,9 +24,73 @@ cViewChannel::cViewChannel(void) {
veStatusInfo = NULL;
veScraperContent = NULL;
veEcmInfo = NULL;
#ifdef USE_ZAPCOCKPIT
veChannelHints = NULL;
veChannelDetail = NULL;
veChannelListDetail = NULL;
veGroupChannelListDetail = NULL;
channelList = NULL;
groupList = NULL;
groupChannelList = NULL;
#endif
}
cViewChannel::~cViewChannel() {
#ifdef USE_ZAPCOCKPIT
delete channelList;
delete groupList;
delete groupChannelList;
#endif
}
void cViewChannel::SetGlobals(cGlobals *globals) {
cView::SetGlobals(globals);
#ifdef USE_ZAPCOCKPIT
if (channelList)
channelList->SetGlobals(globals);
if (groupList)
groupList->SetGlobals(globals);
if (groupChannelList)
groupChannelList->SetGlobals(globals);
#endif
}
void cViewChannel::PreCache(void) {
cView::PreCache();
#ifdef USE_ZAPCOCKPIT
if (channelList) {
channelList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
channelList->PreCache();
}
if (groupList) {
groupList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
groupList->PreCache();
}
if (groupChannelList) {
groupChannelList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
groupChannelList->PreCache();
}
#endif
if (viewElements[(int)eVeDisplayChannel::channellistback])
viewElements[(int)eVeDisplayChannel::channellistback]->UnsetStartAnim();
if (viewElements[(int)eVeDisplayChannel::grouplistback])
viewElements[(int)eVeDisplayChannel::grouplistback]->UnsetStartAnim();
if (viewElements[(int)eVeDisplayChannel::groupchannellistback])
viewElements[(int)eVeDisplayChannel::groupchannellistback]->UnsetStartAnim();
SetViewelementsAnimOut();
}
void cViewChannel::AddChannelViewList(const char *listName, cViewList *viewList) {
#ifdef USE_ZAPCOCKPIT
if (!strcmp(listName, "channellist"))
channelList = dynamic_cast<cViewListChannelList*>(viewList);
else if (!strcmp(listName, "grouplist"))
groupList = dynamic_cast<cViewListGroupList*>(viewList);
else if (!strcmp(listName, "groupchannellist"))
groupChannelList = dynamic_cast<cViewListChannelList*>(viewList);
else
esyslog("skindesigner: invalid view list %s in displaychannel", listName);
#endif
}
void cViewChannel::SetViewElements(void) {
@ -43,6 +107,13 @@ void cViewChannel::SetViewElements(void) {
viewElementNames.insert(pair<string, int>("devices", (int)eVeDisplayChannel::devices));
viewElementNames.insert(pair<string, int>("currentweather", (int)eVeDisplayChannel::currentweather));
viewElementNames.insert(pair<string, int>("scrapercontent", (int)eVeDisplayChannel::scrapercontent));
viewElementNames.insert(pair<string, int>("channelhints", (int)eVeDisplayChannel::channelhints));
viewElementNames.insert(pair<string, int>("channeldetail", (int)eVeDisplayChannel::channeldetail));
viewElementNames.insert(pair<string, int>("channellistback", (int)eVeDisplayChannel::channellistback));
viewElementNames.insert(pair<string, int>("channellistdetail", (int)eVeDisplayChannel::channellistdetail));
viewElementNames.insert(pair<string, int>("grouplistback", (int)eVeDisplayChannel::grouplistback));
viewElementNames.insert(pair<string, int>("groupchannellistback", (int)eVeDisplayChannel::groupchannellistback));
viewElementNames.insert(pair<string, int>("groupchannellistdetail", (int)eVeDisplayChannel::groupchannellistdetail));
viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayChannel::datetime));
viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayChannel::time));
viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayChannel::message));
@ -68,6 +139,7 @@ void cViewChannel::SetViewElementObjects(void) {
else if (dynamic_cast<cVeDcEpgInfo*>(viewElements[i]))
{
veEpgInfo = dynamic_cast<cVeDcEpgInfo*>(viewElements[i]);
veEpgInfo->SetGlobalTimers(&globalTimers);
}
else if (dynamic_cast<cVeDcProgressBar*>(viewElements[i]))
{
@ -76,11 +148,30 @@ void cViewChannel::SetViewElementObjects(void) {
else if (dynamic_cast<cVeDcStatusInfo*>(viewElements[i]))
{
veStatusInfo = dynamic_cast<cVeDcStatusInfo*>(viewElements[i]);
veStatusInfo->SetGlobalTimers(&globalTimers);
}
else if (dynamic_cast<cVeDcScraperContent*>(viewElements[i]))
{
veScraperContent = dynamic_cast<cVeDcScraperContent*>(viewElements[i]);
}
#ifdef USE_ZAPCOCKPIT
else if (dynamic_cast<cVeDcChannelListDetail*>(viewElements[i]))
{
veChannelListDetail = dynamic_cast<cVeDcChannelListDetail*>(viewElements[i]);
}
else if (dynamic_cast<cVeDcGroupChannelListDetail*>(viewElements[i]))
{
veGroupChannelListDetail = dynamic_cast<cVeDcGroupChannelListDetail*>(viewElements[i]);
}
else if (dynamic_cast<cVeDcChannelHints*>(viewElements[i]))
{
veChannelHints = dynamic_cast<cVeDcChannelHints*>(viewElements[i]);
}
else if (dynamic_cast<cVeDcChannelDetail*>(viewElements[i]))
{
veChannelDetail = dynamic_cast<cVeDcChannelDetail*>(viewElements[i]);
}
#endif
else if (dynamic_cast<cVeDcEcmInfo*>(viewElements[i]))
{
veEcmInfo = dynamic_cast<cVeDcEcmInfo*>(viewElements[i]);
@ -98,41 +189,65 @@ void cViewChannel::SetViewElementObjects(void) {
void cViewChannel::ClearVariables(void) {
cView::ClearVariables();
#ifdef USE_ZAPCOCKPIT
viewType = dcDefault;
viewTypeLast = dcDefault;
initExtended = true;
displayList = false;
initList = false;
channelInput = false;
#endif
channelChange = false;
displayChannelGroups = false;
mode = dmDefault;
if (veCustomTokens)
veCustomTokens->Reset();
timersLoaded = false;
globalTimers.ClearTimers();
}
void cViewChannel::GetTimers(void) {
if (!timersLoaded) {
timersLoaded = true;
globalTimers.LoadTimers();
}
}
void cViewChannel::SetChannel(const cChannel *channel, int number) {
channelChange = true;
bool wasChannelGroups = displayChannelGroups;
displayChannelGroups = false;
//check if channelgroups have to be cleared
bool clearChannelGroups = (mode == dmChannelGroups) ? true : false;
mode = dmDefault;
#ifdef USE_ZAPCOCKPIT
//check if channel hints have to be cleared
if (number) {
channelInput = true;
} else if (channelInput) {
channelInput = false;
if (veChannelHints)
veChannelHints->Close();
}
if (veChannelDetail)
veChannelDetail->Clear(true);
#endif
if (veChannelInfo) {
veChannelInfo->Clear();
veChannelInfo->Set(channel, number);
}
if (channel) {
if (!channel->GroupSep()) {
if (wasChannelGroups)
if (clearChannelGroups)
Clear((int)eVeDisplayChannel::channelgroup);
if (veStatusInfo)
veStatusInfo->Set(channel);
if (veEcmInfo)
veEcmInfo->Set(channel);
} else {
displayChannelGroups = true;
Clear((int)eVeDisplayChannel::channelinfo, true);
Clear((int)eVeDisplayChannel::epginfo, true);
Clear((int)eVeDisplayChannel::statusinfo, true);
Clear((int)eVeDisplayChannel::progressbar, true);
Clear((int)eVeDisplayChannel::screenresolution, true);
Clear((int)eVeDisplayChannel::signalquality, true);
Clear((int)eVeDisplayChannel::audioinfo, true);
Clear((int)eVeDisplayChannel::ecminfo, true);
Clear((int)eVeDisplayChannel::devices, true);
Clear((int)eVeDisplayChannel::customtokens, true);
mode = dmChannelGroups;
ClearBasic(false);
if (veChannelGroup)
veChannelGroup->Set(channel);
}
@ -146,9 +261,6 @@ void cViewChannel::SetEvents(const cEvent *present, const cEvent *following) {
if (veProgressBar)
veProgressBar->Set(present);
if (!present && !following)
return;
if (veEpgInfo)
veEpgInfo->Set(present, following);
@ -165,38 +277,329 @@ void cViewChannel::SetMessage(eMessageType type, const char *text) {
}
}
void cViewChannel::Flush(void) {
if (init) {
sdOsd.LockFlush();
#ifdef USE_ZAPCOCKPIT
void cViewChannel::SetViewType(eDisplaychannelView viewType) {
viewTypeLast = this->viewType;
this->viewType = viewType;
}
int cViewChannel::MaxItems(void) {
initList = true;
if (viewType == dcChannelList && channelList)
return channelList->NumItems();
else if (viewType == dcGroupsList && groupList)
return groupList->NumItems();
else if (viewType == dcGroupsChannelList && groupChannelList)
return groupChannelList->NumItems();
return 0;
}
bool cViewChannel::KeyRightOpensChannellist(void) {
if (channelList) {
if (channelList->Button() == eButtonType::left)
return false;
else if (channelList->Button() == eButtonType::right)
return true;
}
if (groupList) {
if (groupList->Button() == eButtonType::left)
return true;
else if (groupList->Button() == eButtonType::right)
return false;
}
return true;
}
void cViewChannel::SetChannelInfo(const cChannel *channel) {
if (!channel)
return;
if (viewType == dcChannelInfo && veChannelDetail) {
ClearOnDisplay();
veChannelDetail->Set(channel);
Render((int)eVeDisplayChannel::channeldetail);
} else if (viewType == dcChannelListInfo && veChannelListDetail) {
veChannelListDetail->Set(channel);
Render((int)eVeDisplayChannel::channellistdetail);
} else if (viewType == dcGroupsChannelListInfo && veGroupChannelListDetail) {
veGroupChannelListDetail->Set(channel);
Render((int)eVeDisplayChannel::groupchannellistdetail);
}
}
void cViewChannel::SetChannelList(const cChannel *channel, int index, bool current) {
displayList = true;
if (viewType == dcChannelList && channelList) {
channelList->Set(channel, index, current);
} else if (viewType == dcGroupsChannelList && groupChannelList) {
groupChannelList->Set(channel, index, current);
}
}
void cViewChannel::SetGroupList(const char *group, int numChannels, int index, bool current) {
displayList = true;
if (groupList) {
groupList->Set(group, numChannels, index, current);
}
}
void cViewChannel::ClearList(void) {
if (viewType == dcChannelList && channelList)
channelList->Clear();
if (viewType == dcGroupsList && groupList)
groupList->Clear();
if (viewType == dcGroupsChannelList && groupChannelList)
groupChannelList->Clear();
}
void cViewChannel::SetNumChannelHints(int num) {
if (veChannelHints)
veChannelHints->SetNumHints(num);
channelHints = true;
}
void cViewChannel::SetChannelHint(const cChannel *channel) {
if (veChannelHints)
veChannelHints->SetHint(channel);
}
#endif //USE_ZAPCOCKPIT
void cViewChannel::Close(void) {
bool doAnim = true;
#ifdef USE_ZAPCOCKPIT
if (viewType != dcDefault || viewTypeLast != dcDefault)
doAnim = false;
#endif
if (doAnim) {
animator->Stop();
animator->Finish();
}
delete animator;
animator = NULL;
UnScaleTv();
ClearVariables();
for (int i=0; i < numViewElements; i++) {
if (!viewElements[i])
continue;
viewElements[i]->Close();
}
#ifdef USE_ZAPCOCKPIT
if (channelList)
channelList->Close();
if (groupList)
groupList->Close();
if (groupChannelList)
groupChannelList->Close();
#endif
// sdOsd.Flush();
sdOsd.DeleteOsd();
}
void cViewChannel::ClearBasic(bool clearBackground) {
if (clearBackground) {
Clear((int)eVeDisplayChannel::background, true);
Clear((int)eVeDisplayChannel::currentweather, true);
}
Clear((int)eVeDisplayChannel::channelinfo, true);
Clear((int)eVeDisplayChannel::epginfo, true);
Clear((int)eVeDisplayChannel::statusinfo, true);
Clear((int)eVeDisplayChannel::scrapercontent, true);
Clear((int)eVeDisplayChannel::progressbar, true);
Clear((int)eVeDisplayChannel::screenresolution, true);
Clear((int)eVeDisplayChannel::signalquality, true);
Clear((int)eVeDisplayChannel::audioinfo, true);
Clear((int)eVeDisplayChannel::ecminfo, true);
Clear((int)eVeDisplayChannel::devices, true);
Clear((int)eVeDisplayChannel::customtokens, true);
}
void cViewChannel::ClearExtended(void) {
#ifdef USE_ZAPCOCKPIT
//exit from channel list
if ((viewTypeLast == dcChannelList || viewTypeLast == dcChannelListInfo) && viewType == dcDefault && channelList) {
channelList->Clear();
Clear((int)eVeDisplayChannel::channellistback);
Clear((int)eVeDisplayChannel::channellistdetail);
SetDirty((int)eVeDisplayChannel::channellistback);
initExtended = true;
init = true;
ShowBasic();
}
//exit from channellist info to channel list
if (viewTypeLast == dcChannelListInfo && viewType == dcChannelList) {
Clear((int)eVeDisplayChannel::channellistdetail);
SetDirty((int)eVeDisplayChannel::channellistdetail);
}
//exit from group list
if (viewTypeLast == dcGroupsList && viewType == dcDefault && groupList) {
groupList->Clear();
Clear((int)eVeDisplayChannel::grouplistback);
SetDirty((int)eVeDisplayChannel::grouplistback);
initExtended = true;
init = true;
ShowBasic();
}
//exit from group channel list to group list
if (viewTypeLast == dcGroupsChannelList && viewType == dcGroupsList && groupChannelList) {
groupChannelList->Clear();
Clear((int)eVeDisplayChannel::groupchannellistback);
SetDirty((int)eVeDisplayChannel::groupchannellistback);
}
//exit from groupchannellist info to groupchannel list
if (viewTypeLast == dcGroupsChannelListInfo && viewType == dcGroupsChannelList) {
Clear((int)eVeDisplayChannel::groupchannellistdetail);
SetDirty((int)eVeDisplayChannel::groupchannellistdetail);
}
//exit from channel list
if ((viewTypeLast == dcGroupsChannelList || viewTypeLast == dcGroupsChannelListInfo) && viewType == dcDefault && groupList && groupChannelList) {
groupList->Clear();
groupChannelList->Clear();
Clear((int)eVeDisplayChannel::grouplistback);
Clear((int)eVeDisplayChannel::groupchannellistback);
Clear((int)eVeDisplayChannel::groupchannellistdetail);
SetDirty((int)eVeDisplayChannel::groupchannellistback);
SetDirty((int)eVeDisplayChannel::grouplistback);
SetDirty((int)eVeDisplayChannel::groupchannellistdetail);
initExtended = true;
init = true;
ShowBasic();
}
//exit from channel info to channel or group list
if (viewTypeLast == dcChannelInfo && (viewType == dcChannelList || viewType == dcGroupsList)) {
Clear((int)eVeDisplayChannel::channeldetail, true);
}
viewTypeLast = dcDefault;
#endif
}
void cViewChannel::ClearOnDisplay(void) {
#ifdef USE_ZAPCOCKPIT
if (viewType == dcChannelInfo && veChannelDetail) {
vector<int> clear = veChannelDetail->GetClearOnDisplay();
for (vector<int>::iterator ve = clear.begin(); ve != clear.end(); ve++) {
Hide(*ve);
}
} else {
cViewElement *listBack = NULL;
if (viewType == dcChannelList)
listBack = viewElements[(int)eVeDisplayChannel::channellistback];
else if (viewType == dcGroupsList)
listBack = viewElements[(int)eVeDisplayChannel::grouplistback];
if (!listBack)
return;
if (listBack->DoClearAll()) {
HideBasic();
return;
}
vector<int> clear = listBack->GetClearOnDisplay();
for (vector<int>::iterator ve = clear.begin(); ve != clear.end(); ve++) {
Hide(*ve);
}
}
#endif
}
void cViewChannel::DrawBasic(bool initial) {
if (initial) {
Render((int)eVeDisplayChannel::background);
Render((int)eVeDisplayChannel::currentweather);
}
if (!displayChannelGroups) {
//normal display
if (!shifting) {
Render((int)eVeDisplayChannel::channelinfo);
Render((int)eVeDisplayChannel::epginfo);
Render((int)eVeDisplayChannel::statusinfo);
Render((int)eVeDisplayChannel::scrapercontent);
Render((int)eVeDisplayChannel::progressbar, channelChange);
Render((int)eVeDisplayChannel::screenresolution);
Render((int)eVeDisplayChannel::signalquality);
Render((int)eVeDisplayChannel::audioinfo);
Render((int)eVeDisplayChannel::ecminfo);
Render((int)eVeDisplayChannel::devices);
Render((int)eVeDisplayChannel::customtokens);
Render((int)eVeDisplayChannel::message);
Render((int)eVeDisplayChannel::channelinfo);
Render((int)eVeDisplayChannel::epginfo);
Render((int)eVeDisplayChannel::statusinfo);
Render((int)eVeDisplayChannel::scrapercontent);
Render((int)eVeDisplayChannel::progressbar, channelChange);
Render((int)eVeDisplayChannel::screenresolution);
Render((int)eVeDisplayChannel::signalquality);
Render((int)eVeDisplayChannel::audioinfo);
Render((int)eVeDisplayChannel::ecminfo);
Render((int)eVeDisplayChannel::devices);
Render((int)eVeDisplayChannel::customtokens);
Render((int)eVeDisplayChannel::message);
#ifdef USE_ZAPCOCKPIT
if (channelHints) {
channelHints = false;
if (veChannelHints) {
if (veChannelHints->Active())
veChannelHints->Close();
veChannelHints->Parse();
veChannelHints->Render();
}
} else {
//channelgroup display
Render((int)eVeDisplayChannel::channelgroup);
}
if (!shifting) {
Render((int)eVeDisplayChannel::datetime);
Render((int)eVeDisplayChannel::time);
}
channelChange = false;
cView::Flush();
#endif
}
void cViewChannel::HideBasic(void) {
for (int ve = (int)eVeDisplayChannel::background; ve <= (int)eVeDisplayChannel::ecminfo; ve++) {
Hide(ve);
}
}
void cViewChannel::ShowBasic(void) {
for (int ve = (int)eVeDisplayChannel::background; ve <= (int)eVeDisplayChannel::ecminfo; ve++) {
Show(ve);
}
}
void cViewChannel::DrawExtended(void) {
#ifdef USE_ZAPCOCKPIT
if (!displayList)
return;
if (initExtended) {
ClearOnDisplay();
initExtended = false;
}
if (viewType == dcChannelList && channelList) {
Render((int)eVeDisplayChannel::channellistback);
channelList->Draw(mcUndefined);
if (initList)
channelList->StartAnimation();
} else if (viewType == dcGroupsList && groupList) {
Render((int)eVeDisplayChannel::grouplistback);
groupList->Draw(mcUndefined);
if (initList)
groupList->StartAnimation();
} else if (viewType == dcGroupsChannelList && groupChannelList) {
Render((int)eVeDisplayChannel::groupchannellistback);
groupChannelList->Draw(mcUndefined);
if (initList)
groupChannelList->StartAnimation();
}
displayList = false;
initList = false;
#endif
}
void cViewChannel::Flush(void) {
#ifdef USE_ZAPCOCKPIT
ClearExtended();
#endif
#ifdef USE_ZAPCOCKPIT
if (viewType < dcChannelList) {
#endif
//Basic Display Handling
if (mode == dmDefault) {
DrawBasic(init);
} else if (mode == dmChannelGroups) {
if (init) {
Render((int)eVeDisplayChannel::background);
Render((int)eVeDisplayChannel::currentweather);
}
Render((int)eVeDisplayChannel::channelgroup);
}
Render((int)eVeDisplayChannel::datetime);
Render((int)eVeDisplayChannel::time);
#ifdef USE_ZAPCOCKPIT
}
#endif
channelChange = false;
#ifdef USE_ZAPCOCKPIT
DrawExtended();
#endif
cView::Flush();
}

View File

@ -2,30 +2,77 @@
#define __VIEWDISPLAYCHANNEL_H
#include "view.h"
#include "../extensions/globaltimers.h"
enum eDisplayMode {
dmDefault,
dmChannelGroups
};
class cViewChannel : public cView {
private:
cVeMessage *veMessage;
cVeCustomTokens *veCustomTokens;
cVeDcChannelInfo *veChannelInfo;
cVeDcChannelGroup *veChannelGroup;
cVeDcEpgInfo *veEpgInfo;
cVeDcProgressBar *veProgressBar;
cVeDcStatusInfo *veStatusInfo;
cVeDcScraperContent *veScraperContent;
cVeDcEcmInfo *veEcmInfo;
cVeMessage *veMessage;
cVeCustomTokens *veCustomTokens;
cVeDcChannelInfo *veChannelInfo;
cVeDcChannelGroup *veChannelGroup;
cVeDcEpgInfo *veEpgInfo;
cVeDcProgressBar *veProgressBar;
cVeDcStatusInfo *veStatusInfo;
cVeDcScraperContent *veScraperContent;
cVeDcEcmInfo *veEcmInfo;
#ifdef USE_ZAPCOCKPIT
cVeDcChannelHints *veChannelHints;
cVeDcChannelDetail *veChannelDetail;
cVeDcChannelListDetail *veChannelListDetail;
cVeDcGroupChannelListDetail *veGroupChannelListDetail;
cViewListChannelList *channelList;
cViewListGroupList *groupList;
cViewListChannelList *groupChannelList;
eDisplaychannelView viewType;
eDisplaychannelView viewTypeLast;
bool initExtended;
bool displayList;
bool initList;
bool channelHints;
bool channelInput;
#endif
bool channelChange;
bool displayChannelGroups;
eDisplayMode mode;
bool timersLoaded;
cGlobalTimers globalTimers;
void SetViewElements(void);
void ClearVariables(void);
void SetViewElementObjects(void);
void ClearBasic(bool clearBackground);
void ClearExtended(void);
void ClearOnDisplay(void);
void DrawBasic(bool initial);
void HideBasic(void);
void ShowBasic(void);
void DrawExtended(void);
public:
cViewChannel(void);
virtual ~cViewChannel(void);
void SetGlobals(cGlobals *globals);
void PreCache(void);
void AddChannelViewList(const char *listName, cViewList *viewList);
void GetTimers(void);
void SetChannel(const cChannel *channel, int number);
void SetEvents(const cEvent *present, const cEvent *following);
void SetMessage(eMessageType type, const char *text);
#ifdef USE_ZAPCOCKPIT
void SetViewType(eDisplaychannelView viewType);
int MaxItems(void);
bool KeyRightOpensChannellist(void);
void SetChannelInfo(const cChannel *channel);
void SetChannelList(const cChannel *channel, int index, bool current);
void SetGroupList(const char *group, int numChannels, int index, bool current);
void ClearList(void);
void SetNumChannelHints(int num);
void SetChannelHint(const cChannel *channel);
#endif
void Close(void);
void Flush(void);
};
#endif //__VIEWDISPLAYCHANNEL_H
#endif //__VIEWDISPLAYCHANNEL_H

View File

@ -108,6 +108,7 @@ void cViewMenu::SetViewElements(void) {
viewElementNames.insert(pair<string, int>("header", (int)eVeDisplayMenu::header));
viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayMenu::datetime));
viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayMenu::time));
viewElementNames.insert(pair<string, int>("vdrstatus", (int)eVeDisplayMenu::vdrstatus));
viewElementNames.insert(pair<string, int>("colorbuttons", (int)eVeDisplayMenu::colorbuttons));
viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayMenu::message));
viewElementNames.insert(pair<string, int>("scrollbar", (int)eVeDisplayMenu::scrollbar));
@ -535,13 +536,11 @@ bool cViewMenu::Init(void) {
}
void cViewMenu::Close(void) {
delete fader;
fader = NULL;
if (FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
if (animator) {
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
}
for (int i=0; i < numSubviews; i++) {
if (subViews[i]) {
@ -558,7 +557,7 @@ void cViewMenu::Close(void) {
}
UnScaleTv();
ClearVariables();
sdOsd.Flush();
// sdOsd.Flush();
sdOsd.DeleteOsd();
}
@ -567,9 +566,6 @@ void cViewMenu::Clear(void) {
}
void cViewMenu::Flush(void) {
if (init) {
sdOsd.LockFlush();
}
bool staticInitiated = false;
if (menuChange) {
newTvFrame = activeSubview->GetTvFrame();
@ -634,45 +630,39 @@ cSubView::cSubView(const char *name) {
header = NULL;
datetime = NULL;
time = NULL;
vdrstatus = NULL;
message = NULL;
sortmode = NULL;
colorbuttons = NULL;
scrollbar = NULL;
viewList = NULL;
viewListVertical = NULL;
viewListHorizontal = NULL;
SetViewElements();
}
cSubView::~cSubView(void) {
delete viewListHorizontal;
delete viewListVertical;
for(vector<cViewList*>::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
delete (*it);
}
}
void cSubView::SetGlobals(cGlobals *globals) {
cView::SetGlobals(globals);
if (viewListVertical)
viewListVertical->SetGlobals(globals);
if (viewListHorizontal)
viewListHorizontal->SetGlobals(globals);
for(vector<cViewList*>::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
(*it)->SetGlobals(globals);
}
}
void cSubView::PreCache(void) {
attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height());
attribs->Cache();
for(vector<cViewList*>::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
cViewList *vl = (*it);
vl->SetPlugId(plugId);
vl->SetPlugMenuId(plugMenuId);
vl->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
vl->PreCache();
}
cView::PreCache();
if (viewListVertical) {
viewListVertical->SetPlugId(plugId);
viewListVertical->SetPlugMenuId(plugMenuId);
viewListVertical->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
viewListVertical->PreCache();
}
if (viewListHorizontal) {
viewListHorizontal->SetPlugId(plugId);
viewListHorizontal->SetPlugMenuId(plugMenuId);
viewListHorizontal->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height());
viewListHorizontal->PreCache();
}
}
bool cSubView::ViewElementSet(int ve) {
@ -705,6 +695,10 @@ void cSubView::SetViewElement(eVeDisplayMenu ve, cViewElement *viewElement) {
if (!time)
time = dynamic_cast<cVeTime*>(viewElement);
break;
case eVeDisplayMenu::vdrstatus:
if (!vdrstatus)
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElement);
break;
case eVeDisplayMenu::message:
if (!message)
message = dynamic_cast<cVeMessage*>(viewElement);
@ -747,6 +741,10 @@ void cSubView::SetViewElementHorizontal(eVeDisplayMenu ve, cViewElement *viewEle
if (!time)
time = dynamic_cast<cVeTime*>(viewElement);
break;
case eVeDisplayMenu::vdrstatus:
if (!vdrstatus)
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElement);
break;
case eVeDisplayMenu::message:
if (!message)
message = dynamic_cast<cVeMessage*>(viewElement);
@ -769,14 +767,7 @@ void cSubView::SetViewElementHorizontal(eVeDisplayMenu ve, cViewElement *viewEle
}
void cSubView::AddViewList(cViewList *viewList) {
eOrientation orientation = viewList->Orientation();
if (orientation == eOrientation::vertical) {
viewListVertical = viewList;
} else if (orientation == eOrientation::horizontal) {
viewListHorizontal = viewList;
} else {
viewListVertical = viewList;
}
viewLists.push_back(viewList);
}
int cSubView::NumListItems(void) {
@ -885,6 +876,7 @@ void cSubView::Clear(void) {
if (background) background->Hide();
if (datetime) datetime->Hide();
if (time) time->Hide();
if (vdrstatus) vdrstatus->Hide();
if (header) header->Hide();
if (colorbuttons) colorbuttons->Hide();
if (scrollbar) scrollbar->Hide();
@ -921,11 +913,17 @@ void cSubView::DrawDynamicVEs(void) {
time->Render();
}
}
if (vdrstatus) {
vdrstatus->Show();
if (vdrstatus->Parse())
vdrstatus->Render();
}
}
void cSubView::DrawList(void) {
if (viewList) {
viewList->Draw(menuCat);
viewList->ResetItemCount();
}
}
@ -967,6 +965,11 @@ void cSubView::SetViewElementObjects(void) {
else if (viewElements[(int)eVeDisplayMenu::time])
time = dynamic_cast<cVeTime*>(viewElements[(int)eVeDisplayMenu::time]);
if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::vdrstatus])
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElementsHorizontal[(int)eVeDisplayMenu::vdrstatus]);
else if (viewElements[(int)eVeDisplayMenu::vdrstatus])
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElements[(int)eVeDisplayMenu::vdrstatus]);
if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::message])
message = dynamic_cast<cVeMessage*>(viewElementsHorizontal[(int)eVeDisplayMenu::message]);
else if (viewElements[(int)eVeDisplayMenu::message])
@ -987,17 +990,24 @@ void cSubView::SetViewElementObjects(void) {
else if (viewElements[(int)eVeDisplayMenu::scrollbar])
scrollbar = dynamic_cast<cVeDmScrollbar*>(viewElements[(int)eVeDisplayMenu::scrollbar]);
if (attribs->Orientation() == eOrientation::horizontal)
viewList = viewListHorizontal;
else
viewList = viewListVertical;
//set appropriate viewlist, orientation and condition have to be considered
for(vector<cViewList*>::iterator it = viewLists.begin(); it != viewLists.end(); it++) {
cViewList *vl = (*it);
if (vl->Orientation() == orientation && vl->Execute()) {
viewList = vl;
break;
}
}
if (!viewList && viewLists.size() > 0) {
viewList = viewLists.front();
}
}
void cSubView::SetViewElements(void) {
viewElementNames.insert(pair<string, int>("background", (int)eVeDisplayMenu::background));
viewElementNames.insert(pair<string, int>("header", (int)eVeDisplayMenu::header));
viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayMenu::datetime));
viewElementNames.insert(pair<string, int>("vdrstatus", (int)eVeDisplayMenu::vdrstatus));
viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayMenu::time));
viewElementNames.insert(pair<string, int>("colorbuttons", (int)eVeDisplayMenu::colorbuttons));
viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayMenu::message));
@ -1071,6 +1081,7 @@ cViewMenuMain::cViewMenuMain(const char *name) : cSubView(name) {
load = NULL;
memory = NULL;
vdrstats = NULL;
vdrstatus = NULL;
temperatures = NULL;
currentSchedule = NULL;
lastRecordings = NULL;
@ -1096,6 +1107,7 @@ void cViewMenuMain::SetViewElements(void) {
viewElementNames.insert(pair<string, int>("systemload", (int)eVeDisplayMenuMain::systemload));
viewElementNames.insert(pair<string, int>("systemmemory", (int)eVeDisplayMenuMain::systemmemory));
viewElementNames.insert(pair<string, int>("vdrstatistics", (int)eVeDisplayMenuMain::vdrstatistics));
viewElementNames.insert(pair<string, int>("vdrstatus", (int)eVeDisplayMenuMain::vdrstatus));
viewElementNames.insert(pair<string, int>("temperatures", (int)eVeDisplayMenuMain::temperatures));
viewElementNames.insert(pair<string, int>("lastrecordings", (int)eVeDisplayMenuMain::lastrecordings));
viewElementNames.insert(pair<string, int>("customtokens", (int)eVeDisplayMenuMain::customtokens));
@ -1145,6 +1157,11 @@ void cViewMenuMain::SetViewElementObjects(void) {
else if (viewElements[(int)eVeDisplayMenuMain::vdrstatistics])
vdrstats = dynamic_cast<cVeDmVdrstatistics*>(viewElements[(int)eVeDisplayMenuMain::vdrstatistics]);
if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::vdrstatus])
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElementsHorizontal[(int)eVeDisplayMenuMain::vdrstatus]);
else if (viewElements[(int)eVeDisplayMenuMain::vdrstatus])
vdrstatus = dynamic_cast<cVeDmVdrstatus*>(viewElements[(int)eVeDisplayMenuMain::vdrstatus]);
if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::temperatures])
temperatures = dynamic_cast<cVeDmTemperatures*>(viewElementsHorizontal[(int)eVeDisplayMenuMain::temperatures]);
else if (viewElements[(int)eVeDisplayMenuMain::temperatures])
@ -1166,6 +1183,7 @@ void cViewMenuMain::SetViewElementObjects(void) {
if (load) load->SetDetached();
if (memory) memory->SetDetached();
if (vdrstats) vdrstats->SetDetached();
if (vdrstatus) vdrstatus->SetDetached();
if (temperatures) temperatures->SetDetached();
if (timers) timers->SetDetached();
if (currentSchedule) currentSchedule->SetDetached();
@ -1202,6 +1220,10 @@ void cViewMenuMain::Clear(void) {
vdrstats->Reset();
vdrstats->Hide();
}
if (vdrstatus) {
vdrstatus->Hide();
}
if (temperatures) {
temperatures->Reset();
@ -1247,11 +1269,6 @@ void cViewMenuMain::DrawStaticVEs(void) {
if (discusage->Parse())
discusage->Render();
}
if (timers) {
timers->Show();
if (timers->Parse())
timers->Render();
}
if (currentSchedule) {
currentSchedule->Show();
if (currentSchedule->Parse())
@ -1275,6 +1292,11 @@ void cViewMenuMain::DrawDynamicVEs(void) {
lastDrawDynamic = now;
}
if (timers) {
timers->Show();
if (timers->Parse())
timers->Render();
}
if (devices) {
devices->Show();
if (devices->Parse())
@ -1295,6 +1317,11 @@ void cViewMenuMain::DrawDynamicVEs(void) {
if (vdrstats->Parse())
vdrstats->Render();
}
if (vdrstatus) {
vdrstatus->Show();
if (vdrstatus->Parse())
vdrstatus->Render();
}
if (temperatures) {
temperatures->Show();
if (temperatures->Parse())
@ -1620,6 +1647,11 @@ void cViewMenuDetail::DrawDynamicVEs(void) {
if (time->Parse())
time->Render();
}
if (vdrstatus) {
vdrstatus->Show();
if (vdrstatus->Parse())
vdrstatus->Render();
}
}
void cViewMenuDetail::DrawDetailedView(void) {

View File

@ -72,6 +72,7 @@ public:
void AddSubview(const char *sSubView, cSubView *subView);
void AddPluginview(cSubView *plugView);
void SetSubView(eMenuCategory MenuCat);
eMenuCategory MenuCat(void) { return menuCat; };
void SetSortMode(eMenuSortMode sortMode);
void SetPluginMenu(int plugId, int plugMenuId);
int NumListItems(void);
@ -114,12 +115,12 @@ protected:
int plugId;
int plugMenuId;
cViewList *viewList;
cViewList *viewListVertical;
cViewList *viewListHorizontal;
vector<cViewList*> viewLists;
cViewElement *background;
cVeDmHeader *header;
cVeDateTime *datetime;
cVeTime *time;
cVeDmVdrstatus *vdrstatus;
cVeMessage *message;
cVeDmSortmode *sortmode;
cVeDmColorbuttons *colorbuttons;
@ -188,6 +189,7 @@ private:
cVeDmSystemload *load;
cVeDmSystemmemory *memory;
cVeDmVdrstatistics *vdrstats;
cVeDmVdrstatus *vdrstatus;
cVeDmTemperatures *temperatures;
cVeDmCurrentschedule *currentSchedule;
cVeDmLastrecordings *lastRecordings;
@ -322,4 +324,4 @@ public:
void SetTransparency(int transparency, bool forceDetached = false);
};
#endif //__VIEWDISPLAYMENU_H
#endif //__VIEWDISPLAYMENU_H

View File

@ -45,7 +45,6 @@ void cViewMessage::SetMessage(eMessageType type, const char *text) {
void cViewMessage::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayMessage::background);
}
Render((int)eVeDisplayMessage::message);

View File

@ -6,6 +6,7 @@
cViewReplay::cViewReplay(void) {
veCustomTokens = NULL;
veTimeshiftTimes = NULL;
veEndTime = NULL;
veMessage = NULL;
veScraperContent = NULL;
@ -45,6 +46,7 @@ void cViewReplay::SetViewElements(void) {
viewElementNames.insert(pair<string, int>("rectitle", (int)eVeDisplayReplay::rectitle));
viewElementNames.insert(pair<string, int>("recinfo", (int)eVeDisplayReplay::recinfo));
viewElementNames.insert(pair<string, int>("currenttime", (int)eVeDisplayReplay::currenttime));
viewElementNames.insert(pair<string, int>("timeshifttimes", (int)eVeDisplayReplay::timeshifttimes));
viewElementNames.insert(pair<string, int>("endtime", (int)eVeDisplayReplay::endtime));
viewElementNames.insert(pair<string, int>("totaltime", (int)eVeDisplayReplay::totaltime));
viewElementNames.insert(pair<string, int>("progressbar", (int)eVeDisplayReplay::progressbar));
@ -92,6 +94,10 @@ void cViewReplay::SetViewElementObjects(void) {
{
veTotalTime = dynamic_cast<cVeDrTotalTime*>(viewElements[i]);
}
else if (dynamic_cast<cVeDrTimeshiftTimes*>(viewElements[i]))
{
veTimeshiftTimes = dynamic_cast<cVeDrTimeshiftTimes*>(viewElements[i]);
}
else if (dynamic_cast<cVeDrEndTime*>(viewElements[i]))
{
veEndTime = dynamic_cast<cVeDrEndTime*>(viewElements[i]);
@ -135,35 +141,106 @@ void cViewReplay::SetViewElementObjects(void) {
}
}
void cViewReplay::PreCache(void) {
cView::PreCache();
SetViewelementsAnimOut();
}
void cViewReplay::ClearVariables(void) {
cView::ClearVariables();
recording = NULL;
lastEvent = NULL;
modeOnly = false;
lastFlush = 0;
lastFlushModeOnly = 0;
message = false;
reclength = -1;
timeShiftActive = false;
timeShiftActive = NoRec;
timeShiftFramesTotal = -1;
timeShiftLength = -1;
timeShiftDuration = "";
timeshiftrest = "";
if (veCustomTokens)
veCustomTokens->Reset();
if (veTimeshiftTimes)
veTimeshiftTimes->Set(cString(""), cString(""), cString(""));
if (veEndTime)
veEndTime->Set(cString(""));
if (veCutMarks)
veCutMarks->Reset();
timersLoaded = false;
globalTimers.ClearTimers();
}
void cViewReplay::SetTimeShift(int framesTotal, int timeShiftLength) {
timeShiftActive = true;
timeShiftFramesTotal = framesTotal;
this->timeShiftLength = timeShiftLength;
void cViewReplay::GetGlobalTimers(void) {
if (!timersLoaded) {
timersLoaded = true;
globalTimers.LoadTimers();
}
}
void cViewReplay::SetTimeShiftValues(int current, int total) {
timeShiftActive = NoRec;
if (!recording)
return;
#if APIVERSNUM >= 20101
int usage = recording->IsInUse();
if (usage & ruTimer)
timeShiftActive = NormalRec;
else {
GetGlobalTimers();
if (globalTimers.IsRecording(recording))
timeShiftActive = NormalRec;
}
#endif
if (!timeShiftActive)
return;
const char *recName = recording->Name();
if (recName && *recName == '@')
timeShiftActive = TimeshiftRec;
const cRecordingInfo *recInfo = recording->Info();
if (!recInfo)
return;
const cSchedule *Schedule = NULL;
if (timeShiftActive == TimeshiftRec) {
{
LOCK_SCHEDULES_READ;
Schedule = Schedules->GetSchedule(recInfo->ChannelID());
}
if (!Schedule)
return;
}
// Get event at actual recording position
const cEvent *event = (timeShiftActive == TimeshiftRec) ? Schedule->GetEventAround(time(0))
: recInfo->GetEvent();
if (!event)
return;
// End of live program
time_t liveEventStop = event->EndTime();
// Begin of timeshift recording
time_t recordingStart = time(0) - recording->LengthInSeconds();
// actual timeshiftlength in sec
timeShiftLength = liveEventStop - recordingStart;
// timeshiftlength until end of live program
timeShiftFramesTotal = total * ((double)timeShiftLength / (double)recording->LengthInSeconds());
// Get event at actual replay position (add 30sec for a better match)
int timeShiftSecondsAfter = (int)(recording->LengthInSeconds() * (1.0 - (double)current / (double)total)) + 30;
if (timeShiftActive == TimeshiftRec) {
const cEvent *eventReplay = Schedule->GetEventAround(time(0) - timeShiftSecondsAfter);
// Display title at replay position
if (veRecTitle && eventReplay != lastEvent) {
veRecTitle->Set(recording, eventReplay, timeShiftActive);
veRecTitle->Parse();
lastEvent = eventReplay;
}
}
int mins = (timeShiftLength / 60) % 60;
int hours = (timeShiftLength / 3600) % 24;
timeShiftDuration = cString::sprintf("%d:%02d", hours, mins);
mins = (timeShiftSecondsAfter / 60) % 60;
hours = (timeShiftSecondsAfter / 3600) % 24;
timeshiftrest = cString::sprintf("%d:%02d", hours, mins);
}
void cViewReplay::SetRecording(const cRecording *recording) {
this->recording = recording;
if (veRecTitle) {
veRecTitle->Set(recording);
}
@ -179,44 +256,66 @@ void cViewReplay::SetTitle(const char *title) {
if (veRecTitle) {
veRecTitle->Set(title);
}
if (veRecInfo) {
veRecInfo->Set(NULL);
}
if (veScraperContent) {
veScraperContent->Set(NULL);
}
}
void cViewReplay::SetCurrent(const char *current) {
if (veCurrentTime)
veCurrentTime->Set(current);
veCurrentTime->Set(current, timeShiftActive);
Render((int)eVeDisplayReplay::currenttime);
}
void cViewReplay::SetTotal(const char *total) {
if (veTotalTime)
veTotalTime->Set(total, timeShiftActive, *timeShiftDuration);
veTotalTime->Set(total, *timeShiftDuration, timeShiftActive);
Render((int)eVeDisplayReplay::totaltime);
}
void cViewReplay::SetTimeshiftTimes(int current, int total) {
if (!veTimeshiftTimes || !recording)
return;
time_t recordingStart = 0;
time_t playbackTime = 0;
if (timeShiftActive) {
recordingStart = time(0) - recording->LengthInSeconds();
playbackTime = time(0) - (int)(recording->LengthInSeconds() * (1.0 - (double)current / (double)total));
} else
recordingStart = recording->Start();
veTimeshiftTimes->Set(TimeString(recordingStart), TimeString(playbackTime), timeshiftrest, timeShiftActive);
Render((int)eVeDisplayReplay::timeshifttimes);
}
void cViewReplay::SetEndTime(int current, int total) {
if (!veEndTime)
if (!veEndTime || !recording)
return;
int totalLength = total;
int recordingLength = reclength;
int recordingLength = recording->LengthInSeconds();
if (timeShiftActive && timeShiftFramesTotal > 0) {
totalLength = timeShiftFramesTotal;
recordingLength = timeShiftLength;
}
double rest = (double)(totalLength - current) / (double)totalLength;
time_t end = time(0) + rest*recordingLength;
veEndTime->Set(TimeString(end));
time_t end = time(0) + rest * recordingLength;
veEndTime->Set(TimeString(end), timeShiftActive);
Render((int)eVeDisplayReplay::endtime);
}
void cViewReplay::SetProgressbar(int current, int total) {
SetTimeShiftValues(current, total);
if (veProgressbar)
veProgressbar->Set(current, total, timeShiftActive, timeShiftFramesTotal);
Render((int)eVeDisplayReplay::progressbar);
}
void cViewReplay::SetMarks(const cMarks *marks, int current, int total) {
if (veCutMarks)
veCutMarks->Set(marks, current, total, timeShiftActive, timeShiftFramesTotal);
if (!veCutMarks)
return;
veCutMarks->Set(marks, current, total, timeShiftActive, timeShiftFramesTotal);
Render((int)eVeDisplayReplay::cutmarks);
}
@ -278,7 +377,6 @@ void cViewReplay::DelayOnPause(void) {
void cViewReplay::Flush(void) {
if (init) {
sdOsd.LockFlush();
if (!modeOnly) {
Render((int)eVeDisplayReplay::background);
Render((int)eVeDisplayReplay::rectitle);
@ -326,4 +424,4 @@ void cViewReplay::SetProgressModeOnly(void) {
veProgressModeOnly->Set(fps, current, total);
if (veProgressModeOnly->Parse())
veProgressModeOnly->Render();
}
}

View File

@ -12,6 +12,7 @@ private:
cVeDrScraperContent *veScraperContent;
cVeDrCurrentTime *veCurrentTime;
cVeDrTotalTime *veTotalTime;
cVeDrTimeshiftTimes *veTimeshiftTimes;
cVeDrEndTime *veEndTime;
cVeDrProgressBar *veProgressbar;
cVeDrCutMarks *veCutMarks;
@ -21,15 +22,21 @@ private:
cVeDrJump *veJump;
cVeDrOnPause *veOnPause;
cVeDrOnPause *veOnPauseModeOnly;
const cRecording *recording;
const cEvent *lastEvent;
bool modeOnly;
time_t lastFlush;
time_t lastFlushModeOnly;
bool message;
int reclength;
bool timeShiftActive;
eRecType_t timeShiftActive;
int timeShiftFramesTotal;
int timeShiftLength;
cString timeshiftrest;
cString timeShiftDuration;
bool timersLoaded;
cGlobalTimers globalTimers;
void GetGlobalTimers(void);
void SetViewElements(void);
void ClearVariables(void);
void SetViewElementObjects(void);
@ -37,13 +44,14 @@ private:
public:
cViewReplay(void);
virtual ~cViewReplay(void);
void PreCache(void);
void SetModeOnly(bool modeOnly) { this->modeOnly = modeOnly; };
void SetRecordingLength(int length) { reclength = length; };
void SetTimeShift(int framesTotal, int timeShiftLength);
void SetRecording(const cRecording *recording);
void SetTimeShiftValues(int current, int total);
void SetTitle(const char *title);
void SetCurrent(const char *current);
void SetTotal(const char *total);
void SetTimeshiftTimes(int current, int total);
void SetEndTime(int current, int total);
void SetProgressbar(int current, int total);
void SetMarks(const cMarks *marks, int current, int total);
@ -56,4 +64,4 @@ public:
void Flush(void);
};
#endif //__VIEWDISPLAYREPLAY_H1
#endif //__VIEWDISPLAYREPLAY_H1

View File

@ -41,14 +41,10 @@ void cViewTracks::ClearVariables(void) {
}
void cViewTracks::Close(void) {
delete fader;
fader = NULL;
if (FadeTime() > 0) {
fader = new cAnimation((cFadable*)this, false);
fader->Fade();
delete fader;
fader = NULL;
}
animator->Stop();
animator->Finish();
delete animator;
animator = NULL;
for (int i=0; i < numViewElements; i++) {
if (viewElements[i]) {
viewElements[i]->Close();
@ -109,12 +105,15 @@ void cViewTracks::SetCurrentTrack(int index) {
void cViewTracks::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayTracks::background);
if (viewList) {
viewList->Draw();
viewList->StartAnimation(true);
}
}
if (change) {
Render((int)eVeDisplayTracks::header);
if (viewList)
if (viewList && !init)
viewList->Draw();
change = false;
}

View File

@ -42,7 +42,6 @@ void cViewVolume::SetVolume(int current, int total, bool mute) {
void cViewVolume::Flush(void) {
if (init) {
sdOsd.LockFlush();
Render((int)eVeDisplayVolume::background);
}
Render((int)eVeDisplayVolume::volume);

View File

@ -13,15 +13,18 @@ cViewElement::cViewElement(void) {
scrollingStarted = false;
blocked = false;
detached = false;
doAnimOut = false;
doStartAnim = true;
waitOnWakeup = true;
startAnimation = true;
viewAnimated = false;
restartAnimation = false;
globals = NULL;
tokenContainer = NULL;
attribs = new cViewElementAttribs((int)eViewElementAttribs::count);
clearAll = false;
detacher = NULL;
fader = NULL;
shifter = NULL;
fader = NULL;
}
cViewElement::cViewElement(const cViewElement &other) {
@ -33,13 +36,16 @@ cViewElement::cViewElement(const cViewElement &other) {
scrollingStarted = false;
blocked = false;
detached = false;
doAnimOut = other.doAnimOut;
doStartAnim = other.doStartAnim;
waitOnWakeup = true;
startAnimation = true;
viewAnimated = false;
restartAnimation = false;
globals = other.globals;
container.Set(other.container.X(), other.container.Y(), other.container.Width(), other.container.Height());
tokenContainer = NULL;
attribs = new cViewElementAttribs(*other.attribs);
clearAll = false;
for (const cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) {
if (cArea *a = dynamic_cast<cArea*>((cAreaNode*)node)) {
@ -50,15 +56,13 @@ cViewElement::cViewElement(const cViewElement &other) {
}
detacher = NULL;
fader = NULL;
shifter = NULL;
fader = NULL;
}
cViewElement::~cViewElement(void) {
delete attribs;
delete detacher;
delete fader;
delete shifter;
delete tokenContainer;
}
@ -103,6 +107,20 @@ cViewElement *cViewElement::CreateViewElement(const char *name, const char *view
e = new cVeDcSignalQuality();
else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displaychannel"))
e = new cVeDcScraperContent();
else if (!strcmp(name, "channelhints"))
e = new cVeDcChannelHints();
else if (!strcmp(name, "channeldetail"))
e = new cVeDcChannelDetail();
else if (!strcmp(name, "channellistback"))
e = new cViewElement();
else if (!strcmp(name, "grouplistback"))
e = new cViewElement();
else if (!strcmp(name, "groupchannellistback"))
e = new cViewElement();
else if (!strcmp(name, "channellistdetail"))
e = new cVeDcChannelListDetail();
else if (!strcmp(name, "groupchannellistdetail"))
e = new cVeDcGroupChannelListDetail();
else if (!strcmp(name, "ecminfo"))
e = new cVeDcEcmInfo();
@ -129,6 +147,8 @@ cViewElement *cViewElement::CreateViewElement(const char *name, const char *view
e = new cVeDmTemperatures();
else if (!strcmp(name, "vdrstatistics"))
e = new cVeDmVdrstatistics();
else if (!strcmp(name, "vdrstatus"))
e = new cVeDmVdrstatus();
else if (!strcmp(name, "lastrecordings"))
e = new cVeDmLastrecordings();
else if (!strcmp(name, "detailheaderepg"))
@ -151,6 +171,8 @@ cViewElement *cViewElement::CreateViewElement(const char *name, const char *view
e = new cVeDrCurrentTime();
else if (!strcmp(name, "totaltime"))
e = new cVeDrTotalTime();
else if (!strcmp(name, "timeshifttimes"))
e = new cVeDrTimeshiftTimes();
else if (!strcmp(name, "endtime"))
e = new cVeDrEndTime();
else if (!strcmp(name, "progressbar") && !strcmp(viewname, "displayreplay"))
@ -268,6 +290,8 @@ bool cViewElement::Execute(void) {
}
void cViewElement::Clear(bool forceClearBackground) {
if (scrollingStarted)
StopScrolling();
tokenContainer->Clear();
for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) {
node->StopBlinkers();
@ -281,6 +305,7 @@ void cViewElement::Clear(bool forceClearBackground) {
}
void cViewElement::Hide(void) {
StopAnimation();
for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) {
sdOsd->Lock();
node->Hide();
@ -306,12 +331,7 @@ void cViewElement::WakeUp(void) {
}
void cViewElement::Close(void) {
delete detacher;
detacher = NULL;
delete fader;
fader = NULL;
delete shifter;
shifter = NULL;
StopAnimation();
StopScrolling();
for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) {
node->StopBlinkers();
@ -322,6 +342,7 @@ void cViewElement::Close(void) {
dirty = true;
init = true;
startAnimation = true;
restartAnimation = false;
drawn = false;
scrollingStarted = false;
blocked = false;
@ -366,25 +387,26 @@ void cViewElement::Render(void) {
cArea *scrollArea = node->ScrollingArea();
if (scrollArea) {
scrollingStarted = true;
cAnimation *scroller = new cAnimation(scrollArea);
scrollers.Add(scroller);
scroller->Start();
cScroller *scroller = new cScroller(scrollArea);
scrollers.push_back(scroller);
cView::AddAnimation(scroller);
}
}
}
dirty = false;
drawn = true;
if (startAnimation) {
if (startAnimation || restartAnimation) {
startAnimation = false;
restartAnimation = false;
StartAnimation();
}
}
void cViewElement::StopScrolling(bool deletePixmaps) {
for (cAnimation *scroller = scrollers.First(); scroller; scroller = scrollers.Next(scroller)) {
scroller->Stop(deletePixmaps);
for (list<cScroller*>::iterator it = scrollers.begin(); it != scrollers.end(); it++) {
cView::RemoveAnimation(*it);
}
scrollers.Clear();
scrollers.clear();
}
void cViewElement::ParseDetached(void) {
@ -397,14 +419,14 @@ void cViewElement::RenderDetached(void) {
}
bool cViewElement::Shifting(void) {
if (attribs->ShiftTime() >= 0) {
if (attribs->ShiftTime() > 0) {
return true;
}
return false;
}
bool cViewElement::Fading(void) {
if (attribs->FadeTime() >= 0) {
if (attribs->FadeTime() > 0) {
return true;
}
return false;
@ -419,25 +441,31 @@ int cViewElement::ShiftTime(void) {
}
int cViewElement::ShiftMode(void) {
return attribs->ShiftMode();
int mode = attribs->ShiftMode();
if (mode < 0) mode = 0;
return mode;
}
void cViewElement::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cViewElement::StartAnimation(void) {
shifter = NULL;
fader = NULL;
if (ShiftTime() > 0) {
cRect shiftbox = CoveredArea();
cPoint ref = cPoint(shiftbox.X(), shiftbox.Y());
cPoint start = ShiftStart(shiftbox);
SetPosition(start, ref);
sdOsd->Flush();
delete shifter;
shifter = new cAnimation((cShiftable*)this, start, ref, true, !viewAnimated);
shifter->Start();
shifter = new cShifter((cShiftable*)this);
if (doAnimOut)
shifter->SetPersistent();
cView::AddAnimation(shifter, doStartAnim);
} else if (FadeTime() > 0) {
SetTransparency(100);
sdOsd->Flush();
delete fader;
fader = new cAnimation((cFadable*)this, true);
fader->Start();
fader = new cFader((cFadable*)this);
if (doAnimOut)
fader->SetPersistent();
cView::AddAnimation(fader, doStartAnim);
}
}
@ -478,7 +506,7 @@ bool cViewElement::Parse(bool forced) {
}
delete detacher;
bool isAnimated = (FadeTime() > 0) || (ShiftTime() > 0);
detacher = new cAnimation((cDetachable*)this, waitOnWakeup, startAnimation && isAnimated);
detacher = new cDetacher((cDetachable*)this, waitOnWakeup, startAnimation && isAnimated);
detacher->Start();
startAnimation = false;
init = false;
@ -546,3 +574,187 @@ cPoint cViewElement::ShiftStart(cRect &shiftbox) {
return start;
}
void cViewElement::StopAnimation(void) {
delete detacher;
detacher = NULL;
if (shifter)
cView::RemoveAnimation(shifter);
if (fader)
cView::RemoveAnimation(fader);
}
/******************************************************************
* helper function (did not find any other common place)
******************************************************************/
bool RecordingIsHD(const cEvent* event, const tChannelID channelID) {
// detect HD from 'info'
bool isHD = false;
int type = -1;
if (event) {
cComponents *Components = (cComponents *)event->Components();
if (Components) {
// detect HD (see also ETSI EN 300 468)
// Stream: 1 = MPEG2-Video, 2 = MPEG2 Audio, 3 = Untertitel, 4 = AC3-Audio, 5 = H.264-Video, 6 = HEAAC-Audio, 7 = DTS/DTS HD audio, 8 = SRM/CPCM data, 9 = HEVC Video, AC4 Audio
// Stream == Video(1|5): 01 = 05 = 4:3, 02 = 03 = 06 = 07 = 16:9, 04 = 08 = >16:9, 09 = 0D = HD 4:3, 0A = 0B = 0E = 0F = HD 16:9, 0C = 10 = HD >16:9
tComponent *Component;
// #1: HVEC (stream content: 9)
Component = Components->GetComponent(0, 9, 0); // recording info: "X 9 <type>"
if (Component) {
isHD = true; // HVEC is always HD, type 4|5|6|7 would be even UHD (see below dedicated detection function)
} else {
// #2: H.264 (stream content: 5)
Component = Components->GetComponent(0, 5, 0); // recording info: "X 5 <type>"
if (Component) {
type = Component->type;
} else {
// #3: MPEG2 (stream content: 1)
Component = Components->GetComponent(0, 1, 0); // recording info: "X 1 <type>"
if (Component) {
type = Component->type;
};
};
};
switch (type) {
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x10:
isHD = true;
};
};
};
if ((isHD == false) && (type == -1) && (!(channelID == tChannelID::InvalidID))) {
// fallback to retrieve via channel (in case of EPG issues)
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(channelID);
#else
const cChannel *channel = Channels.GetByChannelID(channelID);
#endif
if (channel) {
switch (channel->Vtype()) {
case 0x1b: // H.264
case 0x24: // H.265
isHD = true;
break;
};
};
};
return isHD;
};
bool RecordingIsUHD(const cEvent* event, const tChannelID channelID) {
// detect UHD from 'info'
bool isUHD = false;
int type = -1;
if (event) {
cComponents *Components = (cComponents *)event->Components();
if (Components) {
// detect UHD (see also ETSI EN 300 468)
// Stream: 9 = HEVC Video, AC4 Audio
// Stream == Video(9): 00|01|02|03 = HD, 04|05|06|07 = UHD
tComponent *Component;
// HVEC (stream content: 9)
Component = Components->GetComponent(0, 9, 0); // recording info: "X 9 <type>"
if (Component) {
type = Component->type;
};
switch (type) {
case 0x04:
case 0x05:
case 0x06:
case 0x07:
isUHD = true;
};
};
};
if ((isUHD == false) && (type == -1) && (!(channelID == tChannelID::InvalidID))) {
// fallback to retrieve via channel (in case of EPG issues)
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(channelID);
#else
const cChannel *channel = Channels.GetByChannelID(channelID);
#endif
if (channel) {
switch (channel->Vtype()) {
case 0x24: // H.265
isUHD = true;
break;
};
};
};
return isUHD;
};
bool RecordingIsRadio(const cEvent* event, const double FramesPerSecond) {
// detect Radio from 'info'
bool isRadio = false;
bool hasAudio = false;
bool hasVideo = false;
cComponents *Components = (cComponents *)event->Components();
if (Components) {
// Stream: 1 = MPEG2-Video, 2 = MPEG2 Audio, 3 = Untertitel, 4 = AC3-Audio, 5 = H.264-Video, 6 = HEAAC-Audio, 7 = DTS/DTS HD audio, 8 = SRM/CPCM data, 9 = HEVC Video, AC4 Audio
tComponent *Component;
Component = Components->GetComponent(0, 2, 0); // recording info: "X 2 <type>"
if (Component) {
hasAudio = true;
};
Component = Components->GetComponent(0, 4, 0); // recording info: "X 4 <type>"
if (Component) {
hasAudio = true;
};
Component = Components->GetComponent(0, 6, 0); // recording info: "X 6 <type>"
if (Component) {
hasAudio = true;
};
Component = Components->GetComponent(0, 7, 0); // recording info: "X 7 <type>"
if (Component) {
hasAudio = true;
};
Component = Components->GetComponent(0, 1, 0); // recording info: "X 1 <type>"
if (Component) {
hasVideo = true;
};
Component = Components->GetComponent(0, 5, 0); // recording info: "X 5 <type>"
if (Component) {
hasVideo = true;
};
Component = Components->GetComponent(0, 9, 0); // recording info: "X 9 <type>"
if (Component) {
hasVideo = true;
};
};
if ((hasAudio == true) && (hasVideo == false)) {
if (FramesPerSecond < 24) { // workaround for issue of missing "X 1" on some SD channels (e.g. RTL)
isRadio = true;
};
};
return isRadio;
};

View File

@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <list>
#include <vdr/tools.h>
#include "osdwrapper.h"
#include "globals.h"
@ -24,23 +25,28 @@ protected:
bool dirty;
bool blocked;
bool detached;
bool doAnimOut;
bool doStartAnim;
bool waitOnWakeup;
bool scrollingStarted;
bool startAnimation;
bool viewAnimated;
bool restartAnimation;
cGlobals *globals;
cRect container;
cViewElementAttribs *attribs;
vector<int> clearOnDisplay;
bool clearAll;
cList<cAreaNode> areaNodes;
skindesignerapi::cTokenContainer *tokenContainer;
cList<cAnimation> scrollers;
cAnimation *detacher;
cAnimation *fader;
cAnimation *shifter;
list<cScroller*> scrollers;
cDetacher *detacher;
cShifter *shifter;
cFader *fader;
void InheritTokenContainer(void);
void InheritTokenContainerDeep(void);
virtual bool DoScroll(void) { return true; };
cPoint ShiftStart(cRect &shiftbox);
void StopAnimation(void);
public:
cViewElement(void);
cViewElement(const cViewElement &other);
@ -51,11 +57,12 @@ public:
void SetGlobals(cGlobals *globals);
virtual void SetTokenContainer(void);
void SetDetached(void) { detached = true; };
void SetAnimOut(void) { doAnimOut = true; };
void UnsetStartAnim(void) { doStartAnim = false; };
void UnsetWaitOnWakeup(void) { waitOnWakeup = false; };
bool Detached(void);
void SetContainer(int x, int y, int width, int height);
void SetAttributes(vector<stringpair> &attributes);
void SetAnimatedView(void) { viewAnimated = true; };
void AddArea(cAreaNode *area);
void SetAreaX(int x);
void SetAreaY(int y);
@ -76,6 +83,11 @@ public:
void StopScrolling(bool deletePixmaps = true);
eOrientation Orientation(void) { return attribs->Orientation(); };
virtual int Delay(void) { return attribs->Delay(); };
const char *ClearOnDisplay(void) { return attribs->ClearOnDisplay(); };
void SetClearOnDisplay(vector<int> clearOnDisplay) { this->clearOnDisplay = clearOnDisplay; };
vector<int> GetClearOnDisplay(void) { return clearOnDisplay; };
void SetClearAll(void) { clearAll = true; };
bool DoClearAll(void) { return clearAll; };
void ParseDetached(void);
void RenderDetached(void);
bool Shifting(void);
@ -83,7 +95,9 @@ public:
int FadeTime(void);
int ShiftTime(void);
int ShiftMode(void);
void ShiftPositions(cPoint *start, cPoint *end);
void StartAnimation(void);
void SetRestartAnimation(void) { restartAnimation = true; };
virtual void SetTransparency(int transparency, bool force = false);
virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { };
@ -95,4 +109,12 @@ public:
virtual void Debug(bool full = false);
};
#endif //__VIEWELEMENT_H
/******************************************************************
* helper function (did not find any other common place)
******************************************************************/
bool RecordingIsHD(const cEvent* event, const tChannelID channelID);
bool RecordingIsUHD(const cEvent* event, const tChannelID channelID);
bool RecordingIsRadio(const cEvent* event, const double FramesPerSecond);
#endif //__VIEWELEMENT_H

View File

@ -160,12 +160,12 @@ bool cVeMessage::Parse(bool forced) {
* cVeDevices
******************************************************************/
cVeDevices::cVeDevices(void) {
lastRefresh = 0;
initial = true;
devicesIndex = -1;
lastSignalStrength = NULL;
lastSignalQuality = NULL;
recDevices = NULL;
lastRecDevices = NULL;
}
cVeDevices::~cVeDevices(void) {
@ -176,6 +176,8 @@ cVeDevices::~cVeDevices(void) {
lastSignalQuality = NULL;
delete[] recDevices;
recDevices = NULL;
delete[] lastRecDevices;
lastRecDevices = NULL;
mutexDevices.Unlock();
}
@ -193,11 +195,13 @@ void cVeDevices::Init(void) {
lastSignalStrength = new int[numDevices];
lastSignalQuality = new int[numDevices];
recDevices = new bool[numDevices];
lastRecDevices = new bool[numDevices];
mutexDevices.Lock();
for (int i=0; i<numDevices; i++) {
lastSignalStrength[i] = 0;
lastSignalQuality[i] = 0;
recDevices[i] = false;
lastRecDevices[i] = false;
}
mutexDevices.Unlock();
}
@ -205,7 +209,6 @@ void cVeDevices::Init(void) {
void cVeDevices::Close(void) {
devices.clear();
initial = true;
lastRefresh = 0;
numDevices = 0;
mutexDevices.Lock();
delete[] lastSignalStrength;
@ -214,6 +217,8 @@ void cVeDevices::Close(void) {
lastSignalQuality = NULL;
delete[] recDevices;
recDevices = NULL;
delete[] lastRecDevices;
lastRecDevices = NULL;
mutexDevices.Unlock();
cViewElement::Close();
}
@ -243,17 +248,17 @@ void cVeDevices::SetTokenContainer(void) {
bool cVeDevices::Parse(bool forced) {
if (!cViewElement::Parse(forced))
return false;
bool changed = false;
if (initial) {
Init();
initial = false;
changed = true;
} else {
//in light modus content is static
if (light)
return false;
//check if drawing is necessary
if (cTimeMs::Now() - lastRefresh < 500)
return false;
bool changed = false;
for (int i = 0; i < numDevices; i++) {
const cDevice *device = cDevice::GetDevice(devices[i]);
if (!device || !device->NumProvidedSystems()) {
@ -272,22 +277,15 @@ bool cVeDevices::Parse(bool forced) {
if ((signalStrength != lastSigStr) || (signalQuality != lastSigQual)) {
changed = true;
break;
}
}
if (!changed) {
return false;
}
}
}
//check device which currently displays live tv
int deviceLiveTV = -1;
cDevice *primaryDevice = cDevice::PrimaryDevice();
if (primaryDevice) {
if (!primaryDevice->Replaying() || primaryDevice->Transferring())
deviceLiveTV = cDevice::ActualDevice()->DeviceNumber();
else
deviceLiveTV = primaryDevice->DeviceNumber();
// reset recording devices
for (int i = 0; i < numDevices; i++) {
recDevices[i] = false;
}
// check currently recording devices
// BLOCK for LOCK_TIMERS_READ scope !!
{
@ -305,12 +303,40 @@ bool cVeDevices::Parse(bool forced) {
const cDevice *recDevice = RecordControl->Device();
if (recDevice) {
mutexDevices.Lock();
if (recDevices)
recDevices[recDevice->DeviceNumber()] = true;
if (recDevices) {
int d = recDevice->DeviceNumber();
for (int i = 0; i < numDevices; i++) {
if (devices[i] == d) {
recDevices[i] = true;
break;
}
}
}
mutexDevices.Unlock();
}
}
}
} // LOCK_TIMERS_READ
for (int i = 0; i < numDevices; i++) {
if (recDevices[i] != lastRecDevices[i]) {
lastRecDevices[i] = recDevices[i];
changed = true;
}
}
if (!changed) {
return false;
}
//check device which currently displays live tv
int deviceLiveTV = -1;
cDevice *primaryDevice = cDevice::PrimaryDevice();
if (primaryDevice) {
if (!primaryDevice->Replaying() || primaryDevice->Transferring())
deviceLiveTV = cDevice::ActualDevice()->DeviceNumber();
else
deviceLiveTV = primaryDevice->DeviceNumber();
}
//create loop container
@ -326,7 +352,7 @@ bool cVeDevices::Parse(bool forced) {
if (!device || !device->NumProvidedSystems()) {
continue;
}
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::num, *cString::sprintf("%d", i));
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::num, *cString::sprintf("%d", i + 1));
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::type, *(device->DeviceType()));
cCamSlot *camSlot = device->CamSlot();
@ -346,15 +372,9 @@ bool cVeDevices::Parse(bool forced) {
signalQuality = device->SignalQuality();
}
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::signalstrength, *cString::sprintf("%d", signalStrength));
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::signalstrength, *cString::sprintf("%d", signalQuality));
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::livetv, i == deviceLiveTV ? "1" : "0");
bool isRecording = false;
mutexDevices.Lock();
if (recDevices && recDevices[i])
isRecording = true;
mutexDevices.Unlock();
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::recording, isRecording ? "1" : "0");
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::signalquality, *cString::sprintf("%d", signalQuality));
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::livetv, devices[i] == deviceLiveTV ? "1" : "0");
tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::recording, (recDevices && recDevices[i]) ? "1" : "0");
const cChannel *channel = device->GetCurrentlyTunedTransponder();
const cSource *source = (channel) ? Sources.Get(channel->Source()) : NULL;
@ -380,7 +400,6 @@ bool cVeDevices::Parse(bool forced) {
}
SetDirty();
lastRefresh = cTimeMs::Now();
return true;
}
/******************************************************************
@ -538,4 +557,4 @@ bool cVeVolume::Parse(bool forced) {
changed = false;
SetDirty();
return true;
}
}

View File

@ -51,7 +51,6 @@ public:
class cVeDevices : public cViewElement {
private:
bool light;
time_t lastRefresh;
vector<int> devices;
bool initial;
int devicesIndex;
@ -60,6 +59,7 @@ private:
int* lastSignalStrength;
int* lastSignalQuality;
bool* recDevices;
bool* lastRecDevices;
void Init(void);
public:
cVeDevices(void);
@ -107,4 +107,4 @@ public:
void Set(int current, int total, bool mute);
bool Parse(bool forced = false);
};
#endif //__VIEWELEMENTSCOMMON_H
#endif //__VIEWELEMENTSCOMMON_H

View File

@ -1,8 +1,8 @@
#include "viewelementsdisplaychannel.h"
#include "../config.h"
#include "../extensions/helpers.h"
#include "../extensions/timers.h"
#include "../services/scraper2vdr.h"
#include "../services/epgtimer.h"
/******************************************************************
* cVeDcChannelInfo
@ -111,6 +111,9 @@ const char *cVeDcChannelGroup::GetChannelSep(const cChannel *c, bool prev) {
* cVeDcEpgInfo
******************************************************************/
cVeDcEpgInfo::cVeDcEpgInfo(void) {
globalTimers = NULL;
current = NULL;
next = NULL;
}
cVeDcEpgInfo::~cVeDcEpgInfo(void) {
@ -140,57 +143,71 @@ void cVeDcEpgInfo::SetTokenContainer(void) {
InheritTokenContainer();
}
void cVeDcEpgInfo::Set(const cEvent *p, const cEvent *f) {
bool cVeDcEpgInfo::Parse(bool force) {
if (!cViewElement::Parse(force))
return false;
tokenContainer->Clear();
if (p) {
tokenContainer->AddStringToken((int)eDCEpgInfoST::currenttitle, p->Title());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentsubtitle, p->ShortText());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstart, *p->GetTimeString());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstop, *p->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentduration, p->Duration() / 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationhours, p->Duration() / 3600);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationminutes, (p->Duration() / 60) % 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentelapsed, (int)round((time(NULL) - p->StartTime())/60));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentremaining, (int)round((p->EndTime() - time(NULL))/60));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentrecording, EventHasTimer(p));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)p->Vps());
if (current) {
tokenContainer->AddStringToken((int)eDCEpgInfoST::currenttitle, current->Title());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentsubtitle, current->ShortText());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstart, *current->GetTimeString());
tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstop, *current->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentduration, current->Duration() / 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationhours, current->Duration() / 3600);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationminutes, (current->Duration() / 60) % 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentelapsed, (int)round((time(NULL) - current->StartTime())/60));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentremaining, (int)round((current->EndTime() - time(NULL))/60));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentrecording, EventHasTimer(current));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)current->Vps());
}
if (f) {
tokenContainer->AddStringToken((int)eDCEpgInfoST::nexttitle, f->Title());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextsubtitle, f->ShortText());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstart, *f->GetTimeString());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstop, *f->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextduration, f->Duration() / 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationhours, f->Duration() / 3600);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationminutes, (f->Duration() / 60) % 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextrecording, EventHasTimer(f));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)f->Vps());
if (next) {
tokenContainer->AddStringToken((int)eDCEpgInfoST::nexttitle, next->Title());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextsubtitle, next->ShortText());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstart, *next->GetTimeString());
tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstop, *next->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextduration, next->Duration() / 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationhours, next->Duration() / 3600);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationminutes, (next->Duration() / 60) % 60);
tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextrecording, EventHasTimer(next));
tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)next->Vps());
}
SetDirty();
return true;
}
void cVeDcEpgInfo::Close(void) {
current = NULL;
next = NULL;
tokenContainer->Clear();
cViewElement::Close();
}
bool cVeDcEpgInfo::EventHasTimer(const cEvent *e) {
if (!e) return false;
int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
eTimerMatch TimerMatch = tmNone;
const cTimers *timers;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
{
LOCK_TIMERS_READ;
timers = Timers;
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
bool hasTimer = e->HasTimer();
for (int i = 0; i < SortedTimers.Size() && !hasTimer; i++)
if (const cTimer *Timer = SortedTimers[i])
if (Timer->Channel()->GetChannelID() == e->ChannelID())
#else
timers = &Timers;
#endif
const cTimer *Timer = timers->GetMatch(e, &TimerMatch);
if (Timer && Timer->HasFlags(tfActive)) {
if (TimerMatch == tmFull)
return true;
if (TimerMatch == tmPartial) {
const char *fileName = Timer->File();
if (fileName && *fileName == '@')
return true;
}
}
bool hasTimer = false;
for (int i = 0; i < globalTimers->Size() && !hasTimer; i++)
if (const cTimer *Timer = globalTimers->At(i))
if (Timer->Channel() && (Timer->Channel()->GetChannelID() == e->ChannelID()))
if (const cEvent *timerEvent = Timer->Event())
if (e->EventID() == timerEvent->EventID())
hasTimer = true;
@ -213,6 +230,7 @@ void cVeDcProgressBar::Close(void) {
currentLast = -1;
startTime = -1;
duration = -1;
tokenContainer->Clear();
cViewElement::Close();
}
@ -225,16 +243,19 @@ void cVeDcProgressBar::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{remaining}", (int)eDCProgressBarIT::remaining);
tokenContainer->DefineIntToken("{permashift}", (int)eDCProgressBarIT::permashift);
tokenContainer->DefineIntToken("{livebuffer}", (int)eDCProgressBarIT::livebuffer);
tokenContainer->DefineIntToken("{currentremaining}", (int)eDCProgressBarIT::currentremaining);
InheritTokenContainer();
}
void cVeDcProgressBar::Set(const cEvent *p) {
if (!p) {
startTime = -1;
endTime = -1;
duration = -1;
return;
}
startTime = p->StartTime();
endTime = p-> EndTime();
duration = p->Duration();
int current = 0;
@ -258,18 +279,24 @@ void cVeDcProgressBar::Set(const cEvent *p) {
} else {
tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 0);
}
tokenContainer->AddIntToken((int)eDCProgressBarIT::currentremaining, (int)round((endTime - t) / 60));
}
bool cVeDcProgressBar::Parse(bool force) {
if (!cViewElement::Parse(force))
return false;
int current = 0;
time_t t = time(NULL);
if (t > startTime)
current = t - startTime;
if (!(current > currentLast + 3) && !force && !Dirty())
return false;
currentLast = current;
SetDirty();
if (duration <= 0) {
tokenContainer->AddIntToken((int)eDCProgressBarIT::duration, 0);
tokenContainer->AddIntToken((int)eDCProgressBarIT::elapsed, 0);
@ -285,6 +312,7 @@ bool cVeDcProgressBar::Parse(bool force) {
} else {
tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 0);
}
tokenContainer->AddIntToken((int)eDCProgressBarIT::currentremaining, (int)round((endTime - t) / 60));
}
return true;
}
@ -328,21 +356,17 @@ void cVeDcStatusInfo::Set(const cChannel *c) {
bool isDolby = c->Dpid(0);
bool isEncrypted = c->Ca();
bool isRecording = cRecordControls::Active();
int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
for (int i = 0; i < SortedTimers.Size() && !isRecording; i++)
if (const cTimer *Timer = SortedTimers[i])
for (int i = 0; i < globalTimers->Size() && !isRecording; i++) {
if (const cTimer *Timer = globalTimers->At(i)) {
if (Timer->Recording())
isRecording = true;
else if (cEpgTimer_Interface_V1* epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)Timer)) {
if (epgTimer->State() == 'R')
isRecording = true;
}
}
}
tokenContainer->AddIntToken((int)eDCStatusInfoIT::isRadio, isRadio);
tokenContainer->AddIntToken((int)eDCStatusInfoIT::hasVT, hasVT);
@ -466,6 +490,7 @@ void cVeDcScreenResolution::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{screenwidth}", (int)eDCScreenResolutionIT::screenwidth);
tokenContainer->DefineIntToken("{screenheight}", (int)eDCScreenResolutionIT::screenheight);
tokenContainer->DefineIntToken("{isHD}", (int)eDCScreenResolutionIT::isHD);
tokenContainer->DefineIntToken("{isUHD}", (int)eDCScreenResolutionIT::isUHD);
tokenContainer->DefineIntToken("{isWideScreen}", (int)eDCScreenResolutionIT::isWideScreen);
InheritTokenContainer();
}
@ -491,7 +516,8 @@ bool cVeDcScreenResolution::Parse(bool forced) {
SetDirty();
bool isHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD);
bool isUHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD, &isUHD);
bool isWideScreen = false;
string aspectName = GetScreenAspectString(aspect, &isWideScreen);
@ -500,6 +526,7 @@ bool cVeDcScreenResolution::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDCScreenResolutionIT::screenwidth, screenWidth);
tokenContainer->AddIntToken((int)eDCScreenResolutionIT::screenheight, screenHeight);
tokenContainer->AddIntToken((int)eDCScreenResolutionIT::isHD, isHD);
tokenContainer->AddIntToken((int)eDCScreenResolutionIT::isUHD, isUHD);
tokenContainer->AddIntToken((int)eDCScreenResolutionIT::isWideScreen, isWideScreen);
tokenContainer->AddStringToken((int)eDCScreenResolutionST::resolution, resName.c_str());
tokenContainer->AddStringToken((int)eDCScreenResolutionST::aspect, aspectName.c_str());
@ -593,7 +620,8 @@ void cVeDcScraperContent::SetTokenContainer(void) {
void cVeDcScraperContent::Set(const cEvent *e) {
tokenContainer->Clear();
SetPosterBanner(tokenContainer, e, NULL);
if (e)
SetPosterBanner(tokenContainer, e, NULL);
SetDirty();
}
@ -689,3 +717,261 @@ bool cVeDcEcmInfo::CompareECMInfos(sDVBAPIEcmInfo *ecmInfo) {
return false;
return true;
}
/******************************************************************
* cVeDcChannelHints
******************************************************************/
cVeDcChannelHints::cVeDcChannelHints(void) {
hints = NULL;
numHints = 0;
current = 0;
hintsIndex = -1;
active = false;
}
cVeDcChannelHints::~cVeDcChannelHints(void) {
delete[] hints;
}
void cVeDcChannelHints::Close(void) {
cViewElement::Close();
}
void cVeDcChannelHints::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineIntToken("{numhints}", (int)eDCChannelHintsIT::numhints);
tokenContainer->DefineLoopToken("{hints[channelnumber]}", (int)eDCChannelHintsLT::channelnumber);
tokenContainer->DefineLoopToken("{hints[channelname]}", (int)eDCChannelHintsLT::channelname);
tokenContainer->DefineLoopToken("{hints[channelid]}", (int)eDCChannelHintsLT::channelid);
tokenContainer->DefineLoopToken("{hints[channellogoexists]}", (int)eDCChannelHintsLT::channellogoexists);
hintsIndex = tokenContainer->LoopIndex("hints");
InheritTokenContainer();
}
void cVeDcChannelHints::SetNumHints(int num) {
delete[] hints;
numHints = num;
hints = new const cChannel*[num];
current = 0;
active = true;
SetDirty();
}
void cVeDcChannelHints::SetHint(const cChannel *c) {
hints[current++] = c;
}
bool cVeDcChannelHints::Parse(bool forced) {
if (!cViewElement::Parse(forced))
return false;
if (!Dirty())
return false;
if (!hints)
return false;
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDCChannelHintsIT::numhints, numHints);
vector<int> loopInfo;
loopInfo.push_back(numHints);
tokenContainer->CreateLoopTokenContainer(&loopInfo);
for (int i=0; i < numHints; i++) {
if (hints[i]) {
tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelnumber, *cString::sprintf("%d", hints[i]->Number()));
tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelname, hints[i]->Name());
cString channelID = hints[i]->GetChannelID().ToString();
tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelid, *channelID);
bool logoExists = imgCache->LogoExists(*channelID);
tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channellogoexists, *cString::sprintf("%d", logoExists ? 1 : 0));
}
}
return true;
}
/******************************************************************
* cVeDcChannelDetail
******************************************************************/
cVeDcChannelDetail::cVeDcChannelDetail(void) {
channel = NULL;
}
cVeDcChannelDetail::~cVeDcChannelDetail(void) {
channel = NULL;
}
void cVeDcChannelDetail::Close(void) {
channel = NULL;
cViewElement::Close();
}
void cVeDcChannelDetail::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineStringToken("{channelname}", (int)eDCChannelDetailST::channelname);
tokenContainer->DefineStringToken("{currenttitle}", (int)eDCChannelDetailST::currenttitle);
tokenContainer->DefineStringToken("{currentshorttext}", (int)eDCChannelDetailST::currentshorttext);
tokenContainer->DefineStringToken("{currentdescription}", (int)eDCChannelDetailST::currentdescription);
tokenContainer->DefineStringToken("{currentstart}", (int)eDCChannelDetailST::currentstart);
tokenContainer->DefineStringToken("{currentstop}", (int)eDCChannelDetailST::currentstop);
tokenContainer->DefineStringToken("{currentdurationminutes}", (int)eDCChannelDetailST::currentdurationminutes);
tokenContainer->DefineStringToken("{nexttitle}", (int)eDCChannelDetailST::nexttitle);
tokenContainer->DefineStringToken("{nextshorttext}", (int)eDCChannelDetailST::nextshorttext);
tokenContainer->DefineStringToken("{nextdescription}", (int)eDCChannelDetailST::nextdescription);
tokenContainer->DefineStringToken("{nextstart}", (int)eDCChannelDetailST::nextstart);
tokenContainer->DefineStringToken("{nextstop}", (int)eDCChannelDetailST::nextstop);
tokenContainer->DefineStringToken("{nextdurationminutes}", (int)eDCChannelDetailST::nextdurationminutes);
tokenContainer->DefineIntToken("{channelnumber}", (int)eDCChannelDetailIT::channelnumber);
tokenContainer->DefineIntToken("{currentduration}", (int)eDCChannelDetailIT::currentduration);
tokenContainer->DefineIntToken("{currentdurationhours}", (int)eDCChannelDetailIT::currentdurationhours);
tokenContainer->DefineIntToken("{currentelapsed}", (int)eDCChannelDetailIT::currentelapsed);
tokenContainer->DefineIntToken("{currentremaining}", (int)eDCChannelDetailIT::currentremaining);
tokenContainer->DefineIntToken("{nextduration}", (int)eDCChannelDetailIT::nextduration);
tokenContainer->DefineIntToken("{nextdurationhours}", (int)eDCChannelDetailIT::nextdurationhours);
tokenContainer->DefineStringToken("{movietitle}", (int)eScraperST::movietitle);
tokenContainer->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle);
tokenContainer->DefineStringToken("{movietagline}", (int)eScraperST::movietagline);
tokenContainer->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview);
tokenContainer->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres);
tokenContainer->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage);
tokenContainer->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate);
tokenContainer->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity);
tokenContainer->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage);
tokenContainer->DefineStringToken("{posterpath}", (int)eScraperST::posterpath);
tokenContainer->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath);
tokenContainer->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName);
tokenContainer->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath);
tokenContainer->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath);
tokenContainer->DefineStringToken("{seriesname}", (int)eScraperST::seriesname);
tokenContainer->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview);
tokenContainer->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired);
tokenContainer->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork);
tokenContainer->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre);
tokenContainer->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating);
tokenContainer->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus);
tokenContainer->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle);
tokenContainer->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired);
tokenContainer->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars);
tokenContainer->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview);
tokenContainer->DefineStringToken("{episoderating}", (int)eScraperST::episoderating);
tokenContainer->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath);
tokenContainer->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath);
tokenContainer->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path);
tokenContainer->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path);
tokenContainer->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path);
tokenContainer->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path);
tokenContainer->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path);
tokenContainer->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path);
tokenContainer->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path);
tokenContainer->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path);
tokenContainer->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path);
tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie);
tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget);
tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue);
tokenContainer->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult);
tokenContainer->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime);
tokenContainer->DefineIntToken("{isseries}", (int)eScraperIT::isseries);
tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth);
tokenContainer->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight);
tokenContainer->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth);
tokenContainer->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight);
tokenContainer->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection);
tokenContainer->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth);
tokenContainer->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight);
tokenContainer->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth);
tokenContainer->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight);
tokenContainer->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable);
tokenContainer->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber);
tokenContainer->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason);
tokenContainer->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth);
tokenContainer->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight);
tokenContainer->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth);
tokenContainer->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight);
tokenContainer->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width);
tokenContainer->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height);
tokenContainer->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width);
tokenContainer->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height);
tokenContainer->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width);
tokenContainer->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height);
tokenContainer->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width);
tokenContainer->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height);
tokenContainer->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width);
tokenContainer->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height);
tokenContainer->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width);
tokenContainer->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height);
tokenContainer->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width);
tokenContainer->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height);
tokenContainer->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width);
tokenContainer->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height);
tokenContainer->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width);
tokenContainer->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height);
tokenContainer->DefineLoopToken("{actors[name]}", (int)eScraperLT::name);
tokenContainer->DefineLoopToken("{actors[role]}", (int)eScraperLT::role);
tokenContainer->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb);
tokenContainer->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth);
tokenContainer->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight);
actorsIndex = tokenContainer->LoopIndex("actors");
InheritTokenContainer();
}
void cVeDcChannelDetail::Set(const cChannel *c) {
channel = c;
}
bool cVeDcChannelDetail::Parse(bool forced) {
if (!cViewElement::Parse(forced))
return false;
if (!channel)
return false;
SetDirty();
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDCChannelDetailIT::channelnumber, channel->Number());
tokenContainer->AddStringToken((int)eDCChannelDetailST::channelname, channel->Name());
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock;
const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
#endif
const cSchedule *schedule = schedules->GetSchedule(channel);
if (schedule) {
const cEvent *presentEvent = schedule->GetPresentEvent();
if (presentEvent) {
tokenContainer->AddStringToken((int)eDCChannelDetailST::currenttitle, presentEvent->Title());
tokenContainer->AddStringToken((int)eDCChannelDetailST::currentshorttext, presentEvent->ShortText());
tokenContainer->AddStringToken((int)eDCChannelDetailST::currentdescription, presentEvent->Description());
tokenContainer->AddStringToken((int)eDCChannelDetailST::currentstart, *presentEvent->GetTimeString());
tokenContainer->AddStringToken((int)eDCChannelDetailST::currentstop, *presentEvent->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentduration, presentEvent->Duration()/60);
tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentelapsed, (time(0) - presentEvent->StartTime())/60);
tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentremaining, presentEvent->Duration()/60 - (time(0) - presentEvent->StartTime())/60);
tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentdurationhours, presentEvent->Duration() / 3600);
tokenContainer->AddStringToken((int)eDCChannelDetailST::currentdurationminutes, *cString::sprintf("%.2d", (presentEvent->Duration() / 60)%60));
vector<int> loopInfo;
bool scrapInfoAvailable = LoadFullScrapInfo(presentEvent, NULL);
int numActors = NumActors();
loopInfo.push_back(numActors);
tokenContainer->CreateLoopTokenContainer(&loopInfo);
if (scrapInfoAvailable) {
SetFullScrapInfo(tokenContainer, actorsIndex);
}
}
const cList<cEvent> *events = schedule->Events();
if (events && presentEvent) {
const cEvent *nextEvent = events->Next(presentEvent);
if (nextEvent) {
tokenContainer->AddStringToken((int)eDCChannelDetailST::nexttitle, nextEvent->Title());
tokenContainer->AddStringToken((int)eDCChannelDetailST::nextshorttext, nextEvent->ShortText());
tokenContainer->AddStringToken((int)eDCChannelDetailST::nextdescription, nextEvent->Description());
tokenContainer->AddStringToken((int)eDCChannelDetailST::nextstart, *nextEvent->GetTimeString());
tokenContainer->AddStringToken((int)eDCChannelDetailST::nextstop, *nextEvent->GetEndTimeString());
tokenContainer->AddIntToken((int)eDCChannelDetailIT::nextduration, nextEvent->Duration() / 60);
tokenContainer->AddIntToken((int)eDCChannelDetailIT::nextdurationhours, nextEvent->Duration() / 3600);
tokenContainer->AddStringToken((int)eDCChannelDetailST::nextdurationminutes, *cString::sprintf("%.2d", (nextEvent->Duration() / 60)%60));
}
}
}
return true;
}

View File

@ -3,6 +3,7 @@
#include "viewelement.h"
#include "../extensions/scrapmanager.h"
#include "../extensions/globaltimers.h"
#include "../services/dvbapi.h"
/******************************************************************
@ -33,13 +34,18 @@ public:
******************************************************************/
class cVeDcEpgInfo : public cViewElement {
private:
const cEvent *current;
const cEvent *next;
cGlobalTimers *globalTimers;
bool EventHasTimer(const cEvent *e);
public:
cVeDcEpgInfo(void);
virtual ~cVeDcEpgInfo(void);
void SetGlobalTimers(cGlobalTimers *globalTimers) { this->globalTimers = globalTimers; };
void SetTokenContainer(void);
void Set(const cEvent *p, const cEvent *f);
void Set(const cEvent *p, const cEvent *f) { this->current = p; this->next = f; };
void Close(void);
bool Parse(bool forced = false);
};
/******************************************************************
* cVeDcProgressBar
@ -48,6 +54,7 @@ class cVeDcProgressBar : public cViewElement {
private:
int currentLast;
int startTime;
int endTime;
int duration;
int GetLiveBuffer(void);
public:
@ -63,10 +70,12 @@ public:
******************************************************************/
class cVeDcStatusInfo : public cViewElement {
private:
cGlobalTimers *globalTimers;
bool CheckMails(void);
public:
cVeDcStatusInfo(void);
virtual ~cVeDcStatusInfo(void);
void SetGlobalTimers(cGlobalTimers *globalTimers) { this->globalTimers = globalTimers; };
void SetTokenContainer(void);
void Set(const cChannel *c);
};
@ -145,4 +154,53 @@ public:
bool Parse(bool forced = false);
};
#endif //__VIEWELEMENTSDC_H
/******************************************************************
* cVeDcChannelHints
******************************************************************/
class cVeDcChannelHints : public cViewElement {
private:
const cChannel **hints;
int numHints;
int current;
int hintsIndex;
bool active;
public:
cVeDcChannelHints(void);
virtual ~cVeDcChannelHints(void);
void Close(void);
void SetTokenContainer(void);
void SetNumHints(int num);
void SetHint(const cChannel *c);
bool Parse(bool forced = false);
bool Active(void) { return active; };
};
/******************************************************************
* cVeDcChannelDetail
******************************************************************/
class cVeDcChannelDetail : public cViewElement, public cScrapManager {
private:
const cChannel *channel;
int actorsIndex;
public:
cVeDcChannelDetail(void);
virtual ~cVeDcChannelDetail(void);
void Close(void);
void SetTokenContainer(void);
void Set(const cChannel *c);
bool Parse(bool forced = false);
};
class cVeDcChannelListDetail : public cVeDcChannelDetail {
public:
cVeDcChannelListDetail(void) {};
virtual ~cVeDcChannelListDetail(void) {};
};
class cVeDcGroupChannelListDetail : public cVeDcChannelDetail {
public:
cVeDcGroupChannelListDetail(void) {};
virtual ~cVeDcGroupChannelListDetail(void) {};
};
#endif //__VIEWELEMENTSDC_H

View File

@ -1,8 +1,9 @@
#include "viewelementsdisplaymenu.h"
#include "../config.h"
#include <vdr/videodir.h>
#include "../extensions/timers.h"
#include "../extensions/helpers.h"
#include "../extensions/globaltimers.h"
#include "../services/epgtimer.h"
#include <sys/sysinfo.h>
#include <fstream>
#include <iostream>
@ -303,7 +304,7 @@ void cVeDmScrollbar::SetList(int numDisplayed, int offset, int numMax) {
tokenContainer->AddIntToken((int)eDMScrollbarIT::height, barHeight);
tokenContainer->AddIntToken((int)eDMScrollbarIT::offset, barOffset);
tokenContainer->AddIntToken((int)eDMScrollbarIT::hasprev, (offset == 0) ? 0 : 1);
tokenContainer->AddIntToken((int)eDMScrollbarIT::hasnext, (offset + numMax == numDisplayed) ? 0 : 1);
tokenContainer->AddIntToken((int)eDMScrollbarIT::hasnext, (offset + numMax >= numDisplayed) ? 0 : 1);
SetDirty();
}
@ -336,6 +337,7 @@ void cVeDmTimers::SetTokenContainer(void) {
tokenContainer->DefineLoopToken("{timers[channelid]}", (int)eDMTimersLT::channelid);
tokenContainer->DefineLoopToken("{timers[channellogoexists]}", (int)eDMTimersLT::channellogoexists);
tokenContainer->DefineLoopToken("{timers[isremotetimer]}", (int)eDMTimersLT::isremotetimer);
tokenContainer->DefineLoopToken("{timers[remotehost]}", (int)eDMTimersLT::remotehost);
tokenContainer->DefineIntToken("{numtimers}", (int)eDMTimersIT::numtimers);
tokenContainer->DefineIntToken("{numtimerconflicts}", (int)eDMTimersIT::numtimerconflicts);
tokenContainer->DefineIntToken("{timer1exists}", (int)eDMTimersIT::timer1exists);
@ -361,21 +363,15 @@ bool cVeDmTimers::Parse(bool forced) {
if (!cViewElement::Parse(forced))
return false;
tokenContainer->Clear();
cGlobalTimers globalTimers;
globalTimers.LoadTimers();
globalTimers.SortTimers();
globalTimers.MarkLocalTimers();
int timerCount = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
timerCount = Timers->Count();
#else
timerCount = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(timerCount); // local and remote timers
int numTimers = SortedTimers.Size();
int numTimers = globalTimers.Size();
tokenContainer->AddIntToken((int)eDMTimersIT::numtimers, numTimers);
tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, SortedTimers.NumTimerConfilicts());
tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, globalTimers.NumTimerConfilicts());
for (int i=0; i<15; i++) {
if (i < numTimers) {
tokenContainer->AddIntToken(i+2, true);
@ -391,10 +387,12 @@ bool cVeDmTimers::Parse(bool forced) {
for (int i = 0; i < numTimers; i++) {
if (i >=15)
break;
const cTimer *Timer = SortedTimers[i];
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0");
const cTimer *Timer = globalTimers[i];
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, globalTimers.IsRemoteTimer(i) ? "1" : "0");
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::remotehost, globalTimers.RemoteHost(i));
const cEvent *event = Timer->Event();
if (event) {
const char *fileName = Timer->File();
if (event && fileName && !(*fileName == '@')) {
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::title, event->Title());
} else {
const char *File = Setup.FoldersInTimerMenu ? NULL : strrchr(Timer->File(), FOLDERDELIMCHAR);
@ -412,10 +410,17 @@ bool cVeDmTimers::Parse(bool forced) {
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channelid, *channelID);
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channellogoexists, imgCache->LogoExists(*channelID) ? "1" : "0");
}
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::recording, Timer->Recording() ? "1" : "0");
bool isRecording = Timer->Recording();
if (!isRecording) {
if (cEpgTimer_Interface_V1* epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)Timer)) {
if (epgTimer->State() == 'R')
isRecording = true;
}
}
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::recording, isRecording ? "1" : "0");
cString timerDate("");
if (Timer->Recording()) {
if (isRecording) {
timerDate = cString::sprintf("-%s", *TimeString(Timer->StopTime()));
} else {
time_t Now = time(NULL);
@ -434,8 +439,8 @@ bool cVeDmTimers::Parse(bool forced) {
timerDate = cString::sprintf("VPS %s", *timerDate);
}
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::datetime, *timerDate);
tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0");
}
SetDirty();
return true;
}
@ -863,6 +868,41 @@ bool cVeDmVdrstatistics::Parse(bool forced) {
return true;
}
/******************************************************************
* cVeDmVdrstatus
******************************************************************/
cVeDmVdrstatus::cVeDmVdrstatus(void) {
}
cVeDmVdrstatus::~cVeDmVdrstatus(void) {
}
void cVeDmVdrstatus::Close(void) {
cViewElement::Close();
}
void cVeDmVdrstatus::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineIntToken("{vdrIsRecordingsHandlersActive}", (int)eDMVdrstatusIT::vdrIsRecordingsHandlersActive);
tokenContainer->DefineIntToken("{vdrIsRecording}", (int)eDMVdrstatusIT::vdrIsRecording);
tokenContainer->DefineIntToken("{vdrHasTimers}", (int)eDMVdrstatusIT::vdrHasTimers);
InheritTokenContainer();
}
bool cVeDmVdrstatus::Parse(bool forced) {
if (!cViewElement::Parse(forced))
return false;
cGlobalTimers globalTimers;
globalTimers.LoadTimers();
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDMVdrstatusIT::vdrIsRecordingsHandlersActive, RecordingsHandler.Active());
tokenContainer->AddIntToken((int)eDMVdrstatusIT::vdrIsRecording, cRecordControls::Active());
tokenContainer->AddIntToken((int)eDMVdrstatusIT::vdrHasTimers, (globalTimers.Size() > 0));
SetDirty();
return true;
}
/******************************************************************
* cVeDmLastrecordings
******************************************************************/
cVeDmLastrecordings::cVeDmLastrecordings(void) {
@ -893,20 +933,12 @@ bool cVeDmLastrecordings::Parse(bool forced) {
return false;
tokenContainer->Clear();
int numTimers = 0;
// BLOCK for LOCK_TIMERS_READ scope !!
{
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
numTimers = Timers->Count();
#else
numTimers = Timers.Count();
#endif
}
cGlobalSortedTimers SortedTimers(numTimers); // local and remote timers
cGlobalTimers globalTimers;
globalTimers.LoadTimers();
//set number of timers so that it is possible to adapt this viewelement accordingly
tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, SortedTimers.Size());
tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, globalTimers.Size());
list<const cRecording*> orderedRecs;
@ -938,7 +970,7 @@ bool cVeDmLastrecordings::Parse(bool forced) {
int MAX_RECORDINGS = 10;
int availableRecordings = orderedRecs.size();
int numRecordings = min(MAX_RECORDINGS, availableRecordings);
int numRecordings = std::min(MAX_RECORDINGS, availableRecordings);
if (!numRecordings)
return true;
@ -954,12 +986,23 @@ bool cVeDmLastrecordings::Parse(bool forced) {
continue;
}
#endif
string recFullPath = recording->Name() ? recording->Name() : "";
string recName = "";
string recPath = "";
RecName(recFullPath, recName, recPath);
string recSeriesName = "";
const cRecordingInfo *recInfo = recording->Info();
if (recInfo) {
recName = recInfo->Title() ? recInfo->Title() : "";
if (recInfo->Title() && recInfo->ShortText()) {
stringstream ss;
ss << recInfo->Title() << " - " << recInfo->ShortText();
recSeriesName = ss.str();
}
} else {
string recPath = recording->Name() ? recording->Name() : "";
RecName(recPath, recName);
}
if (recName.size() == 0)
recName = recording->Name() ? recording->Name() : "";
cString recDuration = cString::sprintf("%d", recording->LengthInSeconds()/60);
string posterPath = "";
int posterWidth = 0;
int posterHeight = 0;
@ -967,7 +1010,7 @@ bool cVeDmLastrecordings::Parse(bool forced) {
RecPoster(recording, posterWidth, posterHeight, posterPath, hasPoster);
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::name, recName.c_str());
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::seriesname, recPath.c_str());
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::seriesname, recSeriesName.c_str());
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::date, *ShortDateString(recording->Start()));
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::time, *TimeString(recording->Start()));
tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::duration, *recDuration);
@ -980,11 +1023,12 @@ bool cVeDmLastrecordings::Parse(bool forced) {
if (i == MAX_RECORDINGS)
break;
}
SetDirty();
return true;
}
void cVeDmLastrecordings::RecName(string &path, string &name, string &folder) {
void cVeDmLastrecordings::RecName(string &path, string &name) {
size_t delim = path.find_last_of('~');
if (delim == string::npos) {
name = path;
@ -997,12 +1041,6 @@ void cVeDmLastrecordings::RecName(string &path, string &name, string &folder) {
if (name.find('%') == 0) {
name = name.substr(1);
}
folder = path.substr(0, delim);
size_t delim2 = folder.find_last_of('~');
if (delim2 == string::npos) {
return;
}
folder = folder.substr(delim2+1);
}
/******************************************************************
* cVeDmDetailheaderEpg
@ -1164,6 +1202,13 @@ void cVeDmDetailheaderRec::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{durationeventhours}", (int)eDmDetailedHeaderRecIT::durationeventhours);
tokenContainer->DefineIntToken("{recimgavailable}", (int)eDmDetailedHeaderRecIT::recimgavailable);
tokenContainer->DefineIntToken("{recchannelnumber}", (int)eDmDetailedHeaderRecIT::recchannelnumber);
tokenContainer->DefineIntToken("{fps}", (int)eDmDetailedHeaderRecIT::framesPerSecond);
tokenContainer->DefineIntToken("{isHD}", (int)eDmDetailedHeaderRecIT::isHD);
tokenContainer->DefineIntToken("{isUHD}", (int)eDmDetailedHeaderRecIT::isUHD);
tokenContainer->DefineIntToken("{isRadio}", (int)eDmDetailedHeaderRecIT::isRadio);
tokenContainer->DefineIntToken("{isRecording}", (int)eDmDetailedHeaderRecIT::isRecording);
tokenContainer->DefineIntToken("{isInUse}", (int)eDmDetailedHeaderRecIT::isInUse);
tokenContainer->DefineIntToken("{errors}", (int)eDmDetailedHeaderRecIT::errors);
InheritTokenContainer();
}
@ -1183,7 +1228,15 @@ bool cVeDmDetailheaderRec::Parse(bool forced) {
if (info) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::epgname, info->Title());
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::shorttext, info->ShortText());
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::framesPerSecond, info->FramesPerSecond());
int errors = -1;
// ENABLE_ERRORS is only used in VDR-2.5.4 if the coresponding patch is installed, so it can be ignored in other versions
#if (defined (APIVERSNUM) && (APIVERSNUM >= 20505)) || defined (ENABLE_ERRORS)
errors = info->Errors();
#endif
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::errors, errors);
const cEvent *event = info->GetEvent();
tChannelID channelID = tChannelID::InvalidID;
if (event) {
cString recDate = event->GetDateString();
cString recTime = event->GetTimeString();
@ -1208,19 +1261,33 @@ bool cVeDmDetailheaderRec::Parse(bool forced) {
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationevent, duration);
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationeventhours, duration / 60);
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60));
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::isRadio, RecordingIsRadio(event, info->FramesPerSecond())); // detect Radio from 'info' and FPS
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::isRecording, recording->IsInUse() & ruTimer);
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::isInUse, recording->IsInUse());
}
if (info->ChannelName() && (strlen(info->ChannelName()) > 0)) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, info->ChannelName());
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, info->ChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::recchannelnumber, 0); // cannot be provided, for backward compatibility only
channelID = info->ChannelID();
} else {
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_CHANNELS_READ;
const cChannels* channels = Channels;
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByChannelID(info->ChannelID());
#else
cChannels* channels = &Channels;
const cChannel *channel = Channels.GetByChannelID(info->ChannelID());
#endif
const cChannel *channel = channels->GetByChannelID(info->ChannelID());
if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, *channel->GetChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::recchannelnumber, channel->Number());
if (channel) {
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, channel->Name());
tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, *channel->GetChannelID().ToString());
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::recchannelnumber, channel->Number());
channelID = channel->GetChannelID();
}
}
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::isHD, RecordingIsHD(event, channelID)); // detect HD from 'info'
tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::isUHD, RecordingIsUHD(event, channelID)); // detect UHD from 'info'
}
string recImage = "";
string path = recording->FileName() ? recording->FileName() : "";
@ -1320,6 +1387,3 @@ bool cVeDmTablabels::Parse(bool forced) {
}
return true;
}

View File

@ -178,13 +178,25 @@ public:
bool Parse(bool forced = false);
};
/******************************************************************
* cVeDmVdrstatus
******************************************************************/
class cVeDmVdrstatus : public cViewElement {
public:
cVeDmVdrstatus(void);
virtual ~cVeDmVdrstatus(void);
void Close(void);
void SetTokenContainer(void);
bool Parse(bool forced = false);
};
/******************************************************************
* cVeDmLastrecordings
******************************************************************/
class cVeDmLastrecordings : public cViewElement, public cScrapManager {
private:
int recIndex;
void RecName(string &path, string &name, string &folder);
void RecName(string &path, string &name);
public:
cVeDmLastrecordings(void);
virtual ~cVeDmLastrecordings(void);
@ -253,4 +265,4 @@ public:
void SetActiveTab(int activeTab) { SetDirty(); this->activeTab = activeTab; };
bool Parse(bool forced = false);
};
#endif //__VIEWELEMENTSDM_H
#endif //__VIEWELEMENTSDM_H

View File

@ -8,7 +8,9 @@
******************************************************************/
cVeDrRecTitle::cVeDrRecTitle(void) {
recording = NULL;
event = NULL;
title = NULL;
timeShiftActive = NoRec;
}
cVeDrRecTitle::~cVeDrRecTitle(void) {
@ -21,14 +23,38 @@ void cVeDrRecTitle::SetTokenContainer(void) {
tokenContainer->DefineStringToken("{recsubtitle}", (int)eDRRecTitleST::recsubtitle);
tokenContainer->DefineStringToken("{recdate}", (int)eDRRecTitleST::recdate);
tokenContainer->DefineStringToken("{rectime}", (int)eDRRecTitleST::rectime);
tokenContainer->DefineStringToken("{eventstart}", (int)eDRRecTitleST::eventstart);
tokenContainer->DefineStringToken("{eventstop}", (int)eDRRecTitleST::eventstop);
tokenContainer->DefineIntToken("{timeshift}", (int)eDRRecTitleIT::timeshift);
InheritTokenContainer();
}
void cVeDrRecTitle::Set(const cRecording *recording) {
void cVeDrRecTitle::Set(const cRecording *recording, const cEvent *event, eRecType_t timeShiftActive) {
this->timeShiftActive = timeShiftActive;
if (this->title) {
free(this->title);
this->title = NULL;
}
if (this->recording)
this->recording = NULL;
if (this->event)
this->event = NULL;
if (!recording)
return;
this->recording = recording;
if (event)
this->event = event;
}
void cVeDrRecTitle::Set(const char *title) {
if (this->title) {
free(this->title);
this->title = NULL;
}
if (this->recording)
this->recording = NULL;
if (this->event)
this->event = NULL;
if (!title)
return;
free(this->title);
@ -44,17 +70,31 @@ bool cVeDrRecTitle::Parse(bool force) {
tokenContainer->Clear();
if (recording) {
const char *recName = NULL;
const char *recShortText = NULL;
const cRecordingInfo *recInfo = recording->Info();
if (recInfo)
if (event) {
recName = event->Title();
recShortText = event->ShortText();
} else if (recInfo) {
recName = recInfo->Title();
if (!recName)
recShortText = recInfo->ShortText();
}
if (!recName) {
recName = recording->Name();
recShortText = "";
}
tokenContainer->AddStringToken((int)eDRRecTitleST::rectitle, recName);
tokenContainer->AddStringToken((int)eDRRecTitleST::recsubtitle, recInfo ? recInfo->ShortText() : "");
tokenContainer->AddStringToken((int)eDRRecTitleST::recsubtitle, recShortText);
tokenContainer->AddStringToken((int)eDRRecTitleST::recdate, *ShortDateString(recording->Start()));
tokenContainer->AddStringToken((int)eDRRecTitleST::rectime, *TimeString(recording->Start()));
tokenContainer->AddStringToken((int)eDRRecTitleST::rectime, *TimeString(recording->Start()));
tokenContainer->AddIntToken((int)eDRRecTitleIT::timeshift, timeShiftActive);
if (event) {
tokenContainer->AddStringToken((int)eDRRecTitleST::eventstart, *TimeString(event->StartTime()));
tokenContainer->AddStringToken((int)eDRRecTitleST::eventstop, *TimeString(event->EndTime()));
}
} else if (title) {
tokenContainer->AddStringToken((int)eDRRecTitleST::rectitle, title);
tokenContainer->AddStringToken((int)eDRRecTitleST::rectitle, title);
}
SetDirty();
@ -78,6 +118,9 @@ void cVeDrRecInfo::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{screenwidth}", (int)eDRRecInfoIT::screenwidth);
tokenContainer->DefineIntToken("{screenheight}", (int)eDRRecInfoIT::screenheight);
tokenContainer->DefineIntToken("{isHD}", (int)eDRRecInfoIT::isHD);
tokenContainer->DefineIntToken("{isUHD}", (int)eDRRecInfoIT::isUHD);
tokenContainer->DefineIntToken("{isRecording}", (int)eDRRecInfoIT::isRecording);
tokenContainer->DefineIntToken("{isInUse}", (int)eDRRecInfoIT::isInUse);
tokenContainer->DefineIntToken("{isWideScreen}", (int)eDRRecInfoIT::isWideScreen);
InheritTokenContainer();
}
@ -97,7 +140,8 @@ bool cVeDrRecInfo::Parse(bool force) {
double aspect = 0;
cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect);
bool isHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD);
bool isUHD = false;
string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD, &isUHD);
bool isWideScreen = false;
string aspectName = GetScreenAspectString(aspect, &isWideScreen);
@ -105,6 +149,9 @@ bool cVeDrRecInfo::Parse(bool force) {
tokenContainer->AddIntToken((int)eDRRecInfoIT::screenwidth, screenWidth);
tokenContainer->AddIntToken((int)eDRRecInfoIT::screenheight, screenHeight);
tokenContainer->AddIntToken((int)eDRRecInfoIT::isHD, isHD);
tokenContainer->AddIntToken((int)eDRRecInfoIT::isUHD, isUHD);
tokenContainer->AddIntToken((int)eDRRecInfoIT::isRecording, recording->IsInUse() & ruTimer);
tokenContainer->AddIntToken((int)eDRRecInfoIT::isInUse, recording->IsInUse());
tokenContainer->AddIntToken((int)eDRRecInfoIT::isWideScreen, isWideScreen);
tokenContainer->AddStringToken((int)eDRRecInfoST::resolution, resName.c_str());
tokenContainer->AddStringToken((int)eDRRecInfoST::aspect, aspectName.c_str());
@ -119,6 +166,7 @@ bool cVeDrRecInfo::Parse(bool force) {
cVeDrCurrentTime::cVeDrCurrentTime(void) {
changed = true;
current = NULL;
timeShiftActive = NoRec;
}
cVeDrCurrentTime::~cVeDrCurrentTime(void) {
@ -128,14 +176,16 @@ cVeDrCurrentTime::~cVeDrCurrentTime(void) {
void cVeDrCurrentTime::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineStringToken("{reccurrent}", (int)eDRCurrentTimeST::reccurrent);
tokenContainer->DefineIntToken("{timeshift}", (int)eDRCurrentTimeIT::timeshift);
InheritTokenContainer();
}
void cVeDrCurrentTime::Set(const char *current) {
void cVeDrCurrentTime::Set(const char *current, eRecType_t timeShiftActive) {
if (!current)
return;
free(this->current);
this->current = strdup(current);
this->timeShiftActive = timeShiftActive;
changed = true;
}
@ -144,6 +194,7 @@ bool cVeDrCurrentTime::Parse(bool force) {
return false;
tokenContainer->Clear();
tokenContainer->AddStringToken((int)eDRCurrentTimeST::reccurrent, current);
tokenContainer->AddIntToken((int)eDRCurrentTimeIT::timeshift, timeShiftActive);
SetDirty();
changed = false;
return true;
@ -155,8 +206,8 @@ bool cVeDrCurrentTime::Parse(bool force) {
cVeDrTotalTime::cVeDrTotalTime(void) {
changed = true;
total = NULL;
timeshiftActive = false;
timeshiftDuration = NULL;
timeShiftActive = NoRec;
}
cVeDrTotalTime::~cVeDrTotalTime(void) {
@ -172,12 +223,12 @@ void cVeDrTotalTime::SetTokenContainer(void) {
InheritTokenContainer();
}
void cVeDrTotalTime::Set(const char *total, bool timeshiftActive, const char *timeshiftDuration) {
void cVeDrTotalTime::Set(const char *total, const char *timeshiftDuration, eRecType_t timeShiftActive) {
if (!total)
return;
free(this->total);
this->total = strdup(total);
this->timeshiftActive = timeshiftActive;
this->timeShiftActive = timeShiftActive;
free(this->timeshiftDuration);
this->timeshiftDuration = NULL;
if (timeshiftDuration)
@ -191,7 +242,53 @@ bool cVeDrTotalTime::Parse(bool force) {
tokenContainer->Clear();
tokenContainer->AddStringToken((int)eDRTotalTimeST::rectotal, total);
tokenContainer->AddStringToken((int)eDRTotalTimeST::timeshifttotal, timeshiftDuration);
tokenContainer->AddIntToken((int)eDRTotalTimeIT::timeshift, timeshiftActive);
tokenContainer->AddIntToken((int)eDRTotalTimeIT::timeshift, timeShiftActive);
SetDirty();
changed = false;
return true;
}
/******************************************************************
* cVeDrTimeshiftTimes
******************************************************************/
cVeDrTimeshiftTimes::cVeDrTimeshiftTimes(void) {
changed = true;
start = "";
playbacktime = "";
timeshiftrest = "";
timeShiftActive = NoRec;
}
cVeDrTimeshiftTimes::~cVeDrTimeshiftTimes(void) {
}
void cVeDrTimeshiftTimes::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineStringToken("{recstart}", (int)eDRTimeshiftTimesST::recstart);
tokenContainer->DefineStringToken("{playbacktime}", (int)eDRTimeshiftTimesST::playbacktime);
tokenContainer->DefineStringToken("{timeshiftrest}", (int)eDRTimeshiftTimesST::timeshiftrest);
tokenContainer->DefineIntToken("{timeshift}", (int)eDRTimeshiftTimesIT::timeshift);
InheritTokenContainer();
}
void cVeDrTimeshiftTimes::Set(cString start, cString playbacktime, cString timeshiftrest, eRecType_t timeShiftActive) {
this->timeShiftActive = timeShiftActive;
if (strcmp(*this->start, *start) || strcmp(*this->playbacktime, *playbacktime) || strcmp(*this->timeshiftrest, *timeshiftrest)) {
this->start = start;
this->playbacktime = playbacktime;
this->timeshiftrest = timeshiftrest;
changed = true;
}
}
bool cVeDrTimeshiftTimes::Parse(bool force) {
if (!cViewElement::Parse(force) || !changed)
return false;
tokenContainer->Clear();
tokenContainer->AddStringToken((int)eDRTimeshiftTimesST::recstart, *start);
tokenContainer->AddStringToken((int)eDRTimeshiftTimesST::playbacktime, *playbacktime);
tokenContainer->AddStringToken((int)eDRTimeshiftTimesST::timeshiftrest, *timeshiftrest);
tokenContainer->AddIntToken((int)eDRTimeshiftTimesIT::timeshift, timeShiftActive);
SetDirty();
changed = false;
return true;
@ -201,7 +298,9 @@ bool cVeDrTotalTime::Parse(bool force) {
* cVeDrEndTime
******************************************************************/
cVeDrEndTime::cVeDrEndTime(void) {
changed = true;
end = "";
timeShiftActive = NoRec;
}
cVeDrEndTime::~cVeDrEndTime(void) {
@ -210,10 +309,12 @@ cVeDrEndTime::~cVeDrEndTime(void) {
void cVeDrEndTime::SetTokenContainer(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->DefineStringToken("{recend}", (int)eDREndTimeST::recend);
tokenContainer->DefineIntToken("{timeshift}", (int)eDREndTimeIT::timeshift);
InheritTokenContainer();
}
void cVeDrEndTime::Set(cString end) {
void cVeDrEndTime::Set(cString end, eRecType_t timeShiftActive) {
this->timeShiftActive = timeShiftActive;
if (strcmp(*this->end, *end)) {
this->end = end;
changed = true;
@ -225,6 +326,7 @@ bool cVeDrEndTime::Parse(bool force) {
return false;
tokenContainer->Clear();
tokenContainer->AddStringToken((int)eDREndTimeST::recend, *end);
tokenContainer->AddIntToken((int)eDREndTimeIT::timeshift, timeShiftActive);
SetDirty();
changed = false;
return true;
@ -236,8 +338,8 @@ bool cVeDrEndTime::Parse(bool force) {
cVeDrProgressBar::cVeDrProgressBar(void) {
current = -1;
total = -1;
timeshiftActive = false;
timeshiftTotal = -1;
timeShiftActive = NoRec;
changed = true;
}
@ -253,13 +355,14 @@ void cVeDrProgressBar::SetTokenContainer(void) {
InheritTokenContainer();
}
void cVeDrProgressBar::Set(int current, int total, bool timeshiftActive, int timeshiftTotal) {
if (this->current == current)
void cVeDrProgressBar::Set(int current, int total, eRecType_t timeShiftActive, int timeshiftTotal) {
if (!(this->current != current || this->total != total))
return;
this->current = current;
this->total = total;
this->timeshiftActive = timeshiftActive;
this->timeShiftActive = timeShiftActive;
this->timeshiftTotal = timeshiftTotal;
changed = true;
}
@ -270,10 +373,11 @@ bool cVeDrProgressBar::Parse(bool force) {
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDRProgressbarIT::current, current);
tokenContainer->AddIntToken((int)eDRProgressbarIT::total, total);
tokenContainer->AddIntToken((int)eDRProgressbarIT::timeshift, timeshiftActive);
tokenContainer->AddIntToken((int)eDRProgressbarIT::timeshift, timeShiftActive);
tokenContainer->AddIntToken((int)eDRProgressbarIT::timeshifttotal, timeshiftTotal);
SetDirty();
changed = false;
return true;
}
@ -282,12 +386,16 @@ bool cVeDrProgressBar::Parse(bool force) {
******************************************************************/
cVeDrCutMarks::cVeDrCutMarks(void) {
cutmarksIndex = -1;
lastMarks = NULL;
Reset();
changed = true;
marks = NULL;
current = -1;
total = -1;
numMarksLast = 0;
timeShiftActive = NoRec;
timeshiftTotal = -1;
}
cVeDrCutMarks::~cVeDrCutMarks(void) {
delete[] lastMarks;
}
void cVeDrCutMarks::SetTokenContainer(void) {
@ -303,34 +411,25 @@ void cVeDrCutMarks::SetTokenContainer(void) {
InheritTokenContainer();
}
void cVeDrCutMarks::Set(const cMarks *marks, int current, int total, bool timeshiftActive, int timeshiftTotal) {
void cVeDrCutMarks::Set(const cMarks *marks, int current, int total, eRecType_t timeShiftActive, int timeshiftTotal) {
int numMarks = marks->Count();
if (!(this->current != current || this->total != total || this->marks != marks || numMarksLast != numMarks))
return;
this->marks = marks;
numMarksLast = numMarks;
this->current = current;
this->total = total;
this->timeshiftActive = timeshiftActive;
this->timeShiftActive = timeShiftActive;
this->timeshiftTotal = timeshiftTotal;
}
void cVeDrCutMarks::Reset(void) {
marks = NULL;
current = -1;
total = -1;
numMarksLast = 0;
delete[] lastMarks;
lastMarks = NULL;
markActive = -1;
timeshiftActive = false;
timeshiftTotal = -1;
changed = true;
}
bool cVeDrCutMarks::Parse(bool force) {
if (!cViewElement::Parse(force))
if (!cViewElement::Parse(force) || !changed)
return false;
if (!marks || !MarksChanged()) {
return false;
}
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDRCutmarksIT::timeshift, timeshiftActive);
tokenContainer->AddIntToken((int)eDRCutmarksIT::timeshift, timeShiftActive);
int numMarks = marks->Count();
vector<int> cutmarksInfo;
cutmarksInfo.push_back(numMarks);
@ -342,7 +441,7 @@ bool cVeDrCutMarks::Parse(bool force) {
for (const cMark *m = marks->First(); m; m = marks->Next(m)) {
tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::position, *cString::sprintf("%d", m->Position()));
tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::total, *tot);
if (timeshiftActive) {
if (timeShiftActive) {
tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::timeshifttotal, *timeshifttot);
}
tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::startmark, isStartMark ? "1" : "0");
@ -357,61 +456,10 @@ bool cVeDrCutMarks::Parse(bool force) {
isStartMark = !isStartMark;
}
SetDirty();
changed = false;
return true;
}
bool cVeDrCutMarks::MarksChanged(void) {
bool redraw = false;
//if mark was active, we redraw always
if (markActive >= 0) {
markActive = -1;
redraw = true;
}
//check if current position in recording hits mark exactly
for (const cMark *m = marks->First(); m; m = marks->Next(m)) {
if (m->Position() == current) {
markActive = current;
redraw = true;
break;
}
}
if (redraw)
return true;
//if number of marks has changed, redraw
int numMarks = marks->Count();
if (numMarks != numMarksLast) {
RememberMarks();
return true;
}
if (!lastMarks)
return false;
//if position has changed, redraw
int i=0;
for (const cMark *m = marks->First(); m; m = marks->Next(m)) {
if (m->Position() != lastMarks[i]) {
RememberMarks();
return true;
}
i++;
}
return false;
}
void cVeDrCutMarks::RememberMarks(void) {
if (!marks)
return;
numMarksLast = marks->Count();
if (numMarksLast < 1)
return;
delete[] lastMarks;
lastMarks = new int[numMarksLast];
int i=0;
for (const cMark *m = marks->First(); m; m = marks->Next(m)) {
lastMarks[i] = m->Position();
i++;
}
}
/******************************************************************
* cVeDrControlIcons
******************************************************************/
@ -430,13 +478,21 @@ void cVeDrControlIcons::SetTokenContainer(void) {
tokenContainer->DefineIntToken("{play}", (int)eDRControlIconsIT::play);
tokenContainer->DefineIntToken("{pause}", (int)eDRControlIconsIT::pause);
tokenContainer->DefineIntToken("{forward}", (int)eDRControlIconsIT::forward);
tokenContainer->DefineIntToken("{slowforward}", (int)eDRControlIconsIT::slowforward);
tokenContainer->DefineIntToken("{forward1x}", (int)eDRControlIconsIT::forward1x);
tokenContainer->DefineIntToken("{forward2x}", (int)eDRControlIconsIT::forward2x);
tokenContainer->DefineIntToken("{forward3x}", (int)eDRControlIconsIT::forward3x);
tokenContainer->DefineIntToken("{slowforward1x}", (int)eDRControlIconsIT::slowforward1x);
tokenContainer->DefineIntToken("{slowforward2x}", (int)eDRControlIconsIT::slowforward2x);
tokenContainer->DefineIntToken("{slowforward3x}", (int)eDRControlIconsIT::slowforward3x);
tokenContainer->DefineIntToken("{rewind}", (int)eDRControlIconsIT::rewind);
tokenContainer->DefineIntToken("{slowrewind}", (int)eDRControlIconsIT::slowrewind);
tokenContainer->DefineIntToken("{rewind1x}", (int)eDRControlIconsIT::rewind1x);
tokenContainer->DefineIntToken("{rewind2x}", (int)eDRControlIconsIT::rewind2x);
tokenContainer->DefineIntToken("{rewind3x}", (int)eDRControlIconsIT::rewind3x);
tokenContainer->DefineIntToken("{slowrewind1x}", (int)eDRControlIconsIT::slowrewind1x);
tokenContainer->DefineIntToken("{slowrewind2x}", (int)eDRControlIconsIT::slowrewind2x);
tokenContainer->DefineIntToken("{slowrewind3x}", (int)eDRControlIconsIT::slowrewind3x);
InheritTokenContainer();
}
@ -454,13 +510,21 @@ bool cVeDrControlIcons::Parse(bool force) {
bool isPlay = false;
bool isPause = false;
bool isFF = false;
bool isSlowFF = false;
bool isFF1x = false;
bool isFF2x = false;
bool isFF3x = false;
bool isSlowFF1x = false;
bool isSlowFF2x = false;
bool isSlowFF3x = false;
bool isRew = false;
bool isSlowRew = false;
bool isRew1x = false;
bool isRew2x = false;
bool isRew3x = false;
bool isSlowRew1x = false;
bool isSlowRew2x = false;
bool isSlowRew3x = false;
if (speed == -1) {
if (play) {
@ -469,43 +533,69 @@ bool cVeDrControlIcons::Parse(bool force) {
isPause = true;
}
} else if (forward) {
if (!play) {
isPause = true;
}
if (speed == 1) {
isFF1x = true;
if (play)
isFF1x = true;
else
isSlowFF1x = true;
} else if (speed == 2) {
isFF2x = true;
if (play)
isFF2x = true;
else
isSlowFF2x = true;
} else if (speed == 3) {
isFF3x = true;
if (play)
isFF3x = true;
else
isSlowFF3x = true;
} else {
isFF = true;
if (play)
isFF = true;
else
isSlowFF = true;
}
} else {
if (!play) {
isPause = true;
}
if (speed == 1) {
isRew1x = true;
if (play)
isRew1x = true;
else
isSlowRew1x = true;
} else if (speed == 2) {
isRew2x = true;
if (play)
isRew2x = true;
else
isSlowRew2x = true;
} else if (speed == 3) {
isRew3x = true;
if (play)
isRew3x = true;
else
isSlowRew3x = true;
} else {
isRew = true;
if (play)
isRew = true;
else
isSlowRew = true;
}
}
tokenContainer->Clear();
tokenContainer->AddIntToken((int)eDRControlIconsIT::play, isPlay);
tokenContainer->AddIntToken((int)eDRControlIconsIT::pause, isPause);
tokenContainer->AddIntToken((int)eDRControlIconsIT::forward, isFF);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowforward, isSlowFF);
tokenContainer->AddIntToken((int)eDRControlIconsIT::forward1x, isFF1x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::forward2x, isFF2x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::forward3x, isFF3x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowforward1x, isSlowFF1x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowforward2x, isSlowFF2x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowforward3x, isSlowFF3x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind, isRew);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowrewind, isSlowRew);
tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind1x, isRew1x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind2x, isRew2x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind3x, isRew3x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowrewind1x, isSlowRew1x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowrewind2x, isSlowRew2x);
tokenContainer->AddIntToken((int)eDRControlIconsIT::slowrewind3x, isSlowRew3x);
SetDirty();
changed = false;
return true;
@ -534,7 +624,7 @@ void cVeDrProgressModeonly::SetTokenContainer(void) {
}
void cVeDrProgressModeonly::Set(double fps, int current, int total) {
if (this->current == current)
if (!(this->current != current || this->total != total))
return;
this->fps = fps;
this->current = current;

View File

@ -4,19 +4,28 @@
#include "viewelement.h"
#include "../extensions/scrapmanager.h"
// define recordingtypes
enum eRecType_t {
NoRec = 0,
NormalRec,
TimeshiftRec
};
/******************************************************************
* cVeDrRecTitle
******************************************************************/
class cVeDrRecTitle : public cViewElement {
private:
const cRecording *recording;
const cEvent *event;
char *title;
eRecType_t timeShiftActive;
public:
cVeDrRecTitle(void);
virtual ~cVeDrRecTitle(void);
void SetTokenContainer(void);
void Set(const cRecording *recording);
void Set(const char *title);
void Set(const cRecording *recording = NULL, const cEvent *event = NULL, eRecType_t timeShiftActive = NoRec);
void Set(const char *title = NULL);
bool Parse(bool forced = false);
};
@ -41,11 +50,12 @@ class cVeDrCurrentTime : public cViewElement {
private:
bool changed;
char *current;
eRecType_t timeShiftActive;
public:
cVeDrCurrentTime(void);
virtual ~cVeDrCurrentTime(void);
void SetTokenContainer(void);
void Set(const char *current);
void Set(const char *current, eRecType_t timeShiftActive = NoRec);
bool Parse(bool forced = false);
};
@ -56,13 +66,31 @@ class cVeDrTotalTime : public cViewElement {
private:
bool changed;
char *total;
bool timeshiftActive;
eRecType_t timeShiftActive;
char *timeshiftDuration;
public:
cVeDrTotalTime(void);
virtual ~cVeDrTotalTime(void);
void SetTokenContainer(void);
void Set(const char *total, bool timeshiftActive, const char *timeshiftDuration);
void Set(const char *total, const char *timeshiftDuration = NULL, eRecType_t timeShiftActive = NoRec);
bool Parse(bool forced = false);
};
/******************************************************************
* cVeDrTimeshiftTimes
******************************************************************/
class cVeDrTimeshiftTimes : public cViewElement {
private:
cString start;
cString playbacktime;
cString timeshiftrest;
bool changed;
eRecType_t timeShiftActive;
public:
cVeDrTimeshiftTimes(void);
virtual ~cVeDrTimeshiftTimes(void);
void SetTokenContainer(void);
void Set(cString start, cString playbacktime, cString timeshiftrest, eRecType_t timeShiftActive = NoRec);
bool Parse(bool forced = false);
};
@ -72,12 +100,13 @@ public:
class cVeDrEndTime : public cViewElement {
private:
cString end;
eRecType_t timeShiftActive;
bool changed;
public:
cVeDrEndTime(void);
virtual ~cVeDrEndTime(void);
void SetTokenContainer(void);
void Set(cString end);
void Set(cString end, eRecType_t timeShiftActive = NoRec);
bool Parse(bool forced = false);
};
@ -88,14 +117,14 @@ class cVeDrProgressBar : public cViewElement {
private:
int current;
int total;
bool timeshiftActive;
eRecType_t timeShiftActive;
int timeshiftTotal;
bool changed;
public:
cVeDrProgressBar(void);
virtual ~cVeDrProgressBar(void);
void SetTokenContainer(void);
void Set(int current, int total, bool timeshiftActive, int timeshiftTotal);
void Set(int current, int total, eRecType_t timeShiftActive = NoRec, int timeshiftTotal = 0);
bool Parse(bool forced = false);
};
@ -108,19 +137,15 @@ private:
const cMarks *marks;
int current;
int total;
bool timeshiftActive;
eRecType_t timeShiftActive;
int timeshiftTotal;
int numMarksLast;
int *lastMarks;
int markActive;
bool MarksChanged(void);
void RememberMarks(void);
bool changed;
public:
cVeDrCutMarks(void);
virtual ~cVeDrCutMarks(void);
void SetTokenContainer(void);
void Set(const cMarks *marks, int current, int total, bool timeshiftActive, int timeshiftTotal);
void Reset(void);
void Set(const cMarks *marks, int current, int total, eRecType_t timeShiftActive = NoRec, int timeshiftTotal = 0);
bool Parse(bool forced = false);
};
@ -207,4 +232,4 @@ public:
bool Parse(bool forced = false);
};
#endif //__VIEWELEMENTSDR_H
#endif //__VIEWELEMENTSDR_H

View File

@ -1,14 +1,20 @@
#include "viewlist.h"
#include "view.h"
cViewList::cViewList(void) {
globals = NULL;
attribs = new cViewListAttribs((int)eViewListAttribs::count);
numElements = 0;
orientation = eOrientation::vertical;
cleared = true;
itemCount = 0;
listElement = NULL;
currentElement = NULL;
listElements = NULL;
plugId = -1;
plugMenuId = -1;
fader = NULL;
shifter = NULL;
}
cViewList::~cViewList(void) {
@ -24,6 +30,7 @@ cViewList::~cViewList(void) {
}
}
delete[] listElements;
delete tokenContainer;
}
void cViewList::SetGlobals(cGlobals *globals) {
@ -65,6 +72,12 @@ cViewList *cViewList::CreateViewList(const char *name) {
l = new cViewListAudioTracks();
else if (startswith(name, "menuplugin"))
l = new cViewListPlugin();
else if (startswith(name, "channellist"))
l = new cViewListChannelList();
else if (startswith(name, "grouplist"))
l = new cViewListGroupList();
else if (startswith(name, "groupchannellist"))
l = new cViewListChannelList();
else
esyslog("skindesigner: unknown viewlist %s", name);
return l;
@ -90,6 +103,12 @@ cViewElement *cViewList::CreateListElement(const char *name) {
le = new cLeAudioTracks();
else if (startswith(name, "menuplugin"))
le = new cLeMenuPlugin();
else if (startswith(name, "channellist"))
le = new cLeChannelList();
else if (startswith(name, "grouplist"))
le = new cLeGroupList();
else if (startswith(name, "groupchannellist"))
le = new cLeChannelList();
else
esyslog("skindesigner: unknown viewlist %s", name);
return le;
@ -127,6 +146,9 @@ void cViewList::AddCurrentElement(cViewElement *currentElement) {
}
void cViewList::PreCache(void) {
tokenContainer = new skindesignerapi::cTokenContainer();
tokenContainer->CreateContainers();
attribs->SetTokenContainer(tokenContainer);
attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height());
attribs->SetGlobals(globals);
attribs->Cache();
@ -145,7 +167,7 @@ void cViewList::PreCache(void) {
step = width / numElements;
}
int start = 0;
int start = y;
if (align == eAlign::center) {
if (orientation == eOrientation::vertical) {
start = y + (height - numElements * step) / 2;
@ -164,15 +186,25 @@ int cViewList::NumItems(void) {
return numElements;
}
bool cViewList::Execute(void) {
return attribs->DoExecute();
}
eOrientation cViewList::Orientation(void) {
return attribs->Orientation();
}
void cViewList::Draw(eMenuCategory menuCat) {
int current = -1;
int numCalls = 0;
for (int i = 0; i < numElements; i++) {
listElements[i]->SetMenuCategory(menuCat);
if (listElements[i]->Parse()) {
if (listElements[i]->Shifting())
SetShiftParameters(i, numCalls);
if (listElements[i]->Fading() && itemCount == 1) {
listElements[i]->SetSuppressAnimation(true);
}
listElements[i]->Render();
if (listElements[i]->Current()) {
listElements[i]->RenderCurrent();
@ -183,10 +215,11 @@ void cViewList::Draw(eMenuCategory menuCat) {
if (current >= 0 && listElements[current]) {
listElements[current]->WakeCurrent();
}
cleared = false;
}
void cViewList::Clear(void) {
cleared = true;
if (!listElements)
return;
for (int i = 0; i < numElements; i++) {
@ -199,26 +232,121 @@ void cViewList::Clear(void) {
}
void cViewList::Close(void) {
if (shifter)
cView::RemoveAnimation(shifter);
if (fader)
cView::RemoveAnimation(fader);
if (!listElements)
return;
for (int i = 0; i < numElements; i++) {
listElements[i]->StopBlinking();
listElements[i]->StopScrolling();
}
for (int i = 0; i < numElements; i++) {
for (int i = 0; i < numElements; i++)
listElements[i]->Close();
}
void cViewList::SetTransparency(int transparency, bool force) {
for (int i = 0; i < numElements; i++) {
if (listElements[i])
listElements[i]->SetTransparency(transparency, force);
}
}
void cViewList::SetTransparency(int transparency) {
cRect cViewList::CoveredArea(void) {
cRect unionArea;
for (int i = 0; i < numElements; i++) {
if (listElements[i]) {
listElements[i]->SetTransparency(transparency);
}
if (listElements[i])
unionArea.Combine(listElements[i]->CoveredArea());
}
return unionArea;
}
void cViewList::SetPosition(cPoint &position, cPoint &reference, bool force) {
for (int i = 0; i < numElements; i++) {
if (listElements[i])
listElements[i]->SetPosition(position, reference, force);
}
}
void cViewList::ShiftPositions(cPoint *start, cPoint *end) {
cRect shiftbox = CoveredArea();
cPoint startPoint = ShiftStart(shiftbox);
start->Set(startPoint);
end->Set(shiftbox.X(), shiftbox.Y());
}
void cViewList::StartAnimation(bool animOut) {
shifter = NULL;
fader = NULL;
if (ShiftTime() > 0) {
shifter = new cShifter((cShiftable*)this);
if (animOut)
shifter->SetPersistent();
cView::AddAnimation(shifter);
} else if (FadeTime() > 0) {
fader = new cFader((cFadable*)this);
if (animOut)
fader->SetPersistent();
cView::AddAnimation(fader);
}
}
void cViewList::Debug(void) {
esyslog("skindesigner: --- debug viewlist");
attribs->Debug();
}
cPoint cViewList::ShiftStart(cRect &shiftbox) {
eShiftType type = (eShiftType)attribs->ShiftType();
cPoint start;
if (type == eShiftType::none) {
start = attribs->ShiftStartpoint();
} else if (type == eShiftType::left) {
start.SetX(-shiftbox.Width());
start.SetY(shiftbox.Y());
} else if (type == eShiftType::right) {
start.SetX(cOsd::OsdWidth());
start.SetY(shiftbox.Y());
} else if (type == eShiftType::top) {
start.SetX(shiftbox.X());
start.SetY(-shiftbox.Height());
} else if (type == eShiftType::bottom) {
start.SetX(shiftbox.X());
start.SetY(cOsd::OsdHeight());
}
return start;
}
void cViewList::SetShiftParameters(int index, int &call) {
if (itemCount == 1) {
listElements[index]->SetSuppressAnimation(true);
return;
}
listElements[index]->SetSuppressAnimation(cleared);
if (listElements[index]->WasCurrent()) {
if (call == 0) {
call++;
listElements[index]->SetSelectedFromTop();
} else if (call == 1) {
call++;
listElements[index]->SetSelectedFromBottom();
}
} else if (listElements[index]->Current()) {
if (call == 0) {
call++;
listElements[index]->SetSelectedFromBottom();
} else if (call == 1) {
call++;
listElements[index]->SetSelectedFromTop();
}
}
}
void cViewList::CheckListAnimation(int index) {
itemCount++;
if (listElements[index])
listElements[index]->StopListAnimation();
}
/******************************************************************
@ -253,6 +381,7 @@ void cViewListDefault::Prepare(int start, int step) {
listDefault[i] = new cLeMenuDefault(*tpl);
listElements[i] = listDefault[i];
listDefault[i]->SetNumber(i);
listDefault[i]->SetOrientation(orientation);
listDefault[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -335,6 +464,7 @@ void cViewListDefault::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5)
void cViewListDefault::Set(const char *text, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listDefault[index]->StopScrolling();
listDefault[index]->SetCurrent(current);
@ -378,6 +508,7 @@ void cViewListMain::Prepare(int start, int step) {
listMain[i] = new cLeMenuMain(*tpl);
listElements[i] = listMain[i];
listMain[i]->SetNumber(i);
listMain[i]->SetOrientation(orientation);
listMain[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -413,6 +544,7 @@ void cViewListMain::Prepare(int start, int step) {
void cViewListMain::Set(const char *text, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listMain[index]->StopScrolling();
listMain[index]->SetCurrent(current);
@ -457,6 +589,7 @@ void cViewListSchedules::Prepare(int start, int step) {
listSchedules[i] = new cLeMenuSchedules(*tpl);
listElements[i] = listSchedules[i];
listSchedules[i]->SetNumber(i);
listSchedules[i]->SetOrientation(orientation);
listSchedules[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -493,6 +626,7 @@ void cViewListSchedules::Set(const cEvent *event, int index, bool current, bool
const cChannel *channel, bool withDate, eTimerMatch timerMatch) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listSchedules[index]->StopScrolling();
listSchedules[index]->SetCurrent(current);
@ -529,6 +663,7 @@ void cViewListTimers::Prepare(int start, int step) {
listTimers[i] = new cLeMenuTimers(*tpl);
listElements[i] = listTimers[i];
listTimers[i]->SetNumber(i);
listTimers[i]->SetOrientation(orientation);
listTimers[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -564,6 +699,7 @@ void cViewListTimers::Prepare(int start, int step) {
void cViewListTimers::Set(const cTimer *timer, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listTimers[index]->StopScrolling();
listTimers[index]->SetCurrent(current);
@ -599,6 +735,7 @@ void cViewListChannels::Prepare(int start, int step) {
listChannels[i] = new cLeMenuChannels(*tpl);
listElements[i] = listChannels[i];
listChannels[i]->SetNumber(i);
listChannels[i]->SetOrientation(orientation);
listChannels[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -634,6 +771,7 @@ void cViewListChannels::Prepare(int start, int step) {
void cViewListChannels::Set(const cChannel *channel, int index, bool current, bool selectable, bool withProvider) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listChannels[index]->StopScrolling();
listChannels[index]->SetCurrent(current);
@ -669,6 +807,7 @@ void cViewListRecordings::Prepare(int start, int step) {
listRecordings[i] = new cLeMenuRecordings(*tpl);
listElements[i] = listRecordings[i];
listRecordings[i]->SetNumber(i);
listRecordings[i]->SetOrientation(orientation);
listRecordings[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
@ -704,6 +843,7 @@ void cViewListRecordings::Prepare(int start, int step) {
void cViewListRecordings::Set(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listRecordings[index]->StopScrolling();
listRecordings[index]->SetCurrent(current);
@ -742,6 +882,7 @@ void cViewListPlugin::Prepare(int start, int step) {
listPlugin[i] = new cLeMenuPlugin(*tpl);
listElements[i] = listPlugin[i];
listPlugin[i]->SetNumber(i);
listPlugin[i]->SetOrientation(orientation);
listPlugin[i]->SetPlugId(plugId);
listPlugin[i]->SetPlugMenuId(plugMenuId);
listPlugin[i]->SetTokenContainer();
@ -782,6 +923,7 @@ void cViewListPlugin::Prepare(int start, int step) {
void cViewListPlugin::Set(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listPlugin[index]->StopScrolling();
listPlugin[index]->SetCurrent(current);
@ -826,6 +968,7 @@ void cViewListAudioTracks::PreCache(void) {
void cViewListAudioTracks::SetNumtracks(int numTracks) {
this->numTracks = numTracks;
this->numElements = numTracks;
tokenContainer->Clear();
tokenContainer->AddIntToken(0, numTracks);
}
@ -917,3 +1060,121 @@ void cViewListAudioTracks::Draw(void) {
}
}
}
/******************************************************************
* cViewListChannelList
******************************************************************/
cViewListChannelList::cViewListChannelList(void) {
listChannelList = NULL;
}
cViewListChannelList::~cViewListChannelList(void) {
delete[] listChannelList;
}
void cViewListChannelList::Prepare(int start, int step) {
if (!listElement)
return;
cLeChannelList *tpl = dynamic_cast<cLeChannelList*>(listElement);
if (!tpl) return;
listChannelList = new cLeChannelList*[numElements];
listElements = new cListElement*[numElements];
int pos = start;
for (int i = 0; i < numElements; i++) {
listChannelList[i] = new cLeChannelList(*tpl);
listElements[i] = listChannelList[i];
listChannelList[i]->SetNumber(i);
listChannelList[i]->SetOrientation(orientation);
listChannelList[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
x = attribs->X();
y = pos;
width = attribs->Width();
height = step;
listChannelList[i]->SetAreaHeight(height);
} else {
x = pos;
y = attribs->Y();
width = step;
height = attribs->Height();
listChannelList[i]->SetAreaWidth(width);
}
listChannelList[i]->SetContainer(x, y, width, height);
listChannelList[i]->Cache();
pos += step;
}
}
void cViewListChannelList::Set(const cChannel *channel, int index, bool current) {
if (index < 0 || index >= numElements)
return;
itemCount++;
if (!current)
listChannelList[index]->StopScrolling();
listChannelList[index]->SetCurrent(current);
listChannelList[index]->SetSelectable(true);
listChannelList[index]->Set(channel);
}
/******************************************************************
* cViewListGroupList
******************************************************************/
cViewListGroupList::cViewListGroupList(void) {
listGroupList = NULL;
}
cViewListGroupList::~cViewListGroupList(void) {
delete[] listGroupList;
}
void cViewListGroupList::Prepare(int start, int step) {
if (!listElement)
return;
cLeGroupList *tpl = dynamic_cast<cLeGroupList*>(listElement);
if (!tpl) return;
listGroupList = new cLeGroupList*[numElements];
listElements = new cListElement*[numElements];
int pos = start;
for (int i = 0; i < numElements; i++) {
listGroupList[i] = new cLeGroupList(*tpl);
listElements[i] = listGroupList[i];
listGroupList[i]->SetNumber(i);
listGroupList[i]->SetOrientation(orientation);
listGroupList[i]->SetTokenContainer();
int x, y, width, height;
if (orientation == eOrientation::vertical) {
x = attribs->X();
y = pos;
width = attribs->Width();
height = step;
listGroupList[i]->SetAreaHeight(height);
} else {
x = pos;
y = attribs->Y();
width = step;
height = attribs->Height();
listGroupList[i]->SetAreaWidth(width);
}
listGroupList[i]->SetContainer(x, y, width, height);
listGroupList[i]->Cache();
pos += step;
}
}
void cViewListGroupList::Set(const char *group, int numChannels, int index, bool current) {
if (index < 0 || index >= numElements)
return;
CheckListAnimation(index);
if (!current)
listGroupList[index]->StopScrolling();
listGroupList[index]->SetCurrent(current);
listGroupList[index]->SetSelectable(true);
listGroupList[index]->Set(group, numChannels);
}

View File

@ -6,19 +6,27 @@
#include "listelements.h"
#include "area.h"
class cViewList {
class cViewList : public cFadable, public cShiftable {
protected:
int plugId;
int plugMenuId;
cViewListAttribs *attribs;
cRect container;
cGlobals *globals;
skindesignerapi::cTokenContainer *tokenContainer;
int numElements;
eOrientation orientation;
bool cleared;
int itemCount;
cViewElement *listElement;
cViewElement *currentElement;
cListElement **listElements;
cFader *fader;
cShifter *shifter;
virtual void Prepare(int start, int step) {};
cPoint ShiftStart(cRect &shiftbox);
void SetShiftParameters(int index, int &call);
void CheckListAnimation(int index);
public:
cViewList(void);
virtual ~cViewList(void);
@ -34,11 +42,27 @@ public:
void AddCurrentElement(cViewElement *currentElement);
virtual void PreCache(void);
int NumItems(void);
bool Execute(void);
eOrientation Orientation(void);
void Draw(eMenuCategory menuCat);
void Clear(void);
void ResetItemCount(void) { itemCount = 0; };
virtual void Close(void);
void SetTransparency(int transparency);
eButtonType Button(void) { return attribs->Button(); };
//Fadable
bool Detached(void) { return false; };
int Delay(void) { return 0; };
int FadeTime(void) { return attribs->FadeTime(); };
void SetTransparency(int transparency, bool force = false);
//Shiftable
int ShiftTime(void) { return attribs->ShiftTime(); };
int ShiftMode(void) { return attribs->ShiftMode(); };
void ShiftPositions(cPoint *start, cPoint *end);
void SetPosition(cPoint &position, cPoint &reference, bool force = false);
void SetStartShifting(void) { };
void SetEndShifting(void) { };
cRect CoveredArea(void);
void StartAnimation(bool animOut = false);
void Debug(void);
};
@ -152,4 +176,26 @@ public:
void SetCurrentTrack(int index);
void Draw(void);
};
class cViewListChannelList : public cViewList {
private:
cLeChannelList **listChannelList;
protected:
void Prepare(int start, int step);
public:
cViewListChannelList(void);
virtual ~cViewListChannelList(void);
void Set(const cChannel *channel, int index, bool current);
};
class cViewListGroupList : public cViewList {
private:
cLeGroupList **listGroupList;
protected:
void Prepare(int start, int step);
public:
cViewListGroupList(void);
virtual ~cViewListGroupList(void);
void Set(const char *group, int numChannels, int index, bool current);
};
#endif //__VIEWLIST_H

View File

@ -40,6 +40,7 @@ bool cXmlParser::ParseView(void) {
view->SetAttributes(rootAttribs);
cViewMenu *menuView = dynamic_cast<cViewMenu*>(view);
cViewChannel *channelView = dynamic_cast<cViewChannel*>(view);
cViewTracks *tracksView = dynamic_cast<cViewTracks*>(view);
if (!LevelDown())
@ -48,6 +49,13 @@ bool cXmlParser::ParseView(void) {
do {
if (view->ValidViewElement(NodeName())) {
ParseViewElement(NodeName());
} else if (channelView) {
if (view->ValidViewList(NodeName())) {
ParseViewList(NULL, NodeName());
} else {
esyslog("skindesigner: unknown node %s", NodeName());
return false;
}
} else if (menuView) {
if (menuView->ValidSubView(NodeName())) {
ParseSubView(NodeName());
@ -334,7 +342,7 @@ void cXmlParser::ParsePluginViewElement(bool isScrollbar, bool isTabLabels) {
}
}
void cXmlParser::ParseViewList(cView *subView) {
void cXmlParser::ParseViewList(cView *subView, const char *listName) {
if (!view)
return;
@ -345,7 +353,11 @@ void cXmlParser::ParseViewList(cView *subView) {
name = view->GetViewName();
vector<stringpair> attribs = ParseAttributes();
cViewList *viewList = cViewList::CreateViewList(name);
cViewList *viewList = NULL;
if (!listName)
viewList = cViewList::CreateViewList(name);
else
viewList = cViewList::CreateViewList(listName);
viewList->SetAttributes(attribs);
if (!LevelDown())
@ -353,7 +365,11 @@ void cXmlParser::ParseViewList(cView *subView) {
do {
if (CheckNodeName("currentelement")) {
cViewElement *currentElement = cViewList::CreateCurrentElement(name);
cViewElement *currentElement = NULL;
if (!listName)
currentElement = cViewList::CreateCurrentElement(name);
else
currentElement = cViewList::CreateCurrentElement(listName);
currentElement->SetOsd(sdOsd);
vector<stringpair> attribsList = ParseAttributes();
currentElement->SetAttributes(attribsList);
@ -375,7 +391,11 @@ void cXmlParser::ParseViewList(cView *subView) {
LevelUp();
viewList->AddCurrentElement(currentElement);
} else if (CheckNodeName("listelement")) {
cViewElement *listElement = cViewList::CreateListElement(name);
cViewElement *listElement = NULL;
if (!listName)
listElement = cViewList::CreateListElement(name);
else
listElement = cViewList::CreateListElement(listName);
listElement->SetOsd(sdOsd);
vector<stringpair> attribsList = ParseAttributes();
listElement->SetAttributes(attribsList);
@ -402,8 +422,12 @@ void cXmlParser::ParseViewList(cView *subView) {
if (subView)
subView->AddViewList(viewList);
else
view->AddViewList(viewList);
else if (listName) {
cViewChannel *channelView = dynamic_cast<cViewChannel*>(view);
channelView->AddChannelViewList(listName, viewList);
} else {
view->AddViewList(viewList);
}
}

View File

@ -29,7 +29,7 @@ private:
bool ParseSubView(string name);
void ParseViewElement(string name, cView *subView = NULL);
void ParsePluginViewElement(bool isScrollbar = false, bool isTabLabels = false);
void ParseViewList(cView *subView = NULL);
void ParseViewList(cView *subView = NULL, const char *listName = NULL);
void ParseViewTab(cView *subView);
void ParseViewTabPlugin(void);
void ParseGrid(void);

View File

@ -3,6 +3,7 @@
cSkinDesigner::cSkinDesigner(string skin, cTheme *theme) : cSkin(skin.c_str(), theme) {
init = true;
initialized = false;
this->skin = skin;
backupSkin = NULL;
@ -106,11 +107,11 @@ cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) {
return displayMessage;
}
void cSkinDesigner::Reload(void) {
int cSkinDesigner::Reload(void) {
dsyslog("skindesigner: forcing full reload of templates");
if (cOsd::IsOpen()) {
esyslog("skindesigner: OSD is open, close first!");
return;
return 2;
}
cStopWatch watch;
@ -120,11 +121,13 @@ void cSkinDesigner::Reload(void) {
if (!backupSkin)
backupSkin = new cSkinLCARS();
useBackupSkin = true;
return 1;
} else {
CacheViews();
useBackupSkin = false;
watch.Stop("templates reloaded and cache created");
}
return 0;
}
void cSkinDesigner::ListAvailableFonts(void) {
@ -171,6 +174,7 @@ void cSkinDesigner::ListCustomTokens(void) {
}
skindesignerapi::ISkinDisplayPlugin *cSkinDesigner::GetDisplayPlugin(int plugId) {
Init();
map<int, cViewPlugin*>::iterator hit = pluginViews.find(plugId);
if (hit == pluginViews.end())
return NULL;
@ -194,7 +198,7 @@ void cSkinDesigner::Init(void) {
config.SetOSDFonts();
}
dsyslog("skindesigner: initializing skin %s", skin.c_str());
config.CheckDecimalPoint();
plgManager->Reset();
@ -212,11 +216,13 @@ void cSkinDesigner::Init(void) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
backupSkin = new cSkinLCARS();
useBackupSkin = true;
initialized = true;
} else {
CacheViews();
watch.Stop("templates loaded and caches created");
}
init = false;
initialized = true;
}
else if (config.OsdFontsChanged())
{
@ -235,6 +241,14 @@ void cSkinDesigner::Init(void) {
watch.Stop("templates loaded and caches created");
}
}
else if (config.PlayModeChanged())
{
dsyslog ("skindesigner: drop image cache");
if (imgCache)
delete imgCache;
imgCache = new cImageCache();
imgCache->SetPathes();
}
}
void cSkinDesigner::DeleteViews(void) {

View File

@ -22,6 +22,7 @@ class cSkinDesigner;
class cSkinDesigner : public cSkin {
private:
bool init;
bool initialized;
string skin;
cSkinLCARS *backupSkin;
bool useBackupSkin;
@ -51,7 +52,8 @@ public:
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
virtual cSkinDisplayMessage *DisplayMessage(void);
void ActivateBackupSkin(void) { useBackupSkin = true; };
void Reload(void);
int Reload(void);
bool Initialized(void) { return initialized; };
void ListAvailableFonts(void);
bool SetCustomIntToken(string option);
bool SetCustomStringToken(string option);

View File

@ -29,8 +29,72 @@ void cSDDisplayChannel::SetMessage(eMessageType Type, const char *Text) {
view->SetMessage(Type, Text);
}
#ifdef USE_ZAPCOCKPIT
void cSDDisplayChannel::SetViewType(eDisplaychannelView ViewType) {
if (!ok)
return;
view->SetViewType(ViewType);
}
int cSDDisplayChannel::MaxItems(void) {
if (!ok)
return 0;
return view->MaxItems();
}
bool cSDDisplayChannel::KeyRightOpensChannellist(void) {
if (!ok)
return true;
return view->KeyRightOpensChannellist();
}
void cSDDisplayChannel::SetChannelInfo(const cChannel *Channel) {
if (!ok)
return;
view->SetChannelInfo(Channel);
}
void cSDDisplayChannel::SetChannelList(const cChannel *Channel, int Index, bool Current) {
if (!ok)
return;
view->SetChannelList(Channel, Index, Current);
}
void cSDDisplayChannel::SetGroupList(const char *Group, int NumChannels, int Index, bool Current) {
if (!ok)
return;
view->SetGroupList(Group, NumChannels, Index, Current);
}
void cSDDisplayChannel::SetGroupChannelList(const cChannel *Channel, int Index, bool Current) {
if (!ok)
return;
}
void cSDDisplayChannel::ClearList(void) {
if (!ok)
return;
view->ClearList();
}
void cSDDisplayChannel::SetNumChannelHints(int Num) {
if (!ok)
return;
view->SetNumChannelHints(Num);
}
void cSDDisplayChannel::SetChannelHint(const cChannel *Channel) {
if (!ok)
return;
view->SetChannelHint(Channel);
}
#endif //USE_ZAPCOCKPIT
void cSDDisplayChannel::Flush(void) {
if (!ok)
return;
view->GetTimers();
view->Flush();
}

View File

@ -6,7 +6,11 @@
#include "coreengine/definitions.h"
#include "coreengine/viewdisplaychannel.h"
#ifdef USE_ZAPCOCKPIT
class cSDDisplayChannel : public cSkinDisplayChannelExtended {
#else
class cSDDisplayChannel : public cSkinDisplayChannel {
#endif
private:
cViewChannel *view;
bool ok;
@ -16,6 +20,18 @@ public:
virtual void SetChannel(const cChannel *Channel, int Number);
virtual void SetEvents(const cEvent *Present, const cEvent *Following);
virtual void SetMessage(eMessageType Type, const char *Text);
#ifdef USE_ZAPCOCKPIT
virtual void SetViewType(eDisplaychannelView ViewType);
virtual int MaxItems(void);
virtual bool KeyRightOpensChannellist(void);
virtual void SetChannelInfo(const cChannel *Channel);
virtual void SetChannelList(const cChannel *Channel, int Index, bool Current);
virtual void SetGroupList(const char *Group, int NumChannels, int Index, bool Current);
virtual void SetGroupChannelList(const cChannel *Channel, int Index, bool Current);
virtual void ClearList(void);
virtual void SetNumChannelHints(int Num);
virtual void SetChannelHint(const cChannel *Channel);
#endif
virtual void Flush(void);
};
#endif //__DISPLAYCHANNEL_H

View File

@ -69,7 +69,7 @@ void cSDDisplayMenu::SetMessage(eMessageType Type, const char *Text) {
view->SetMessage(Type, Text);
}
bool cSDDisplayMenu::SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch) {
bool cSDDisplayMenu::SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch, bool TimerActive) {
if (!view)
return false;
if (Index == 0) {
@ -133,18 +133,27 @@ void cSDDisplayMenu::SetScrollbar(int Total, int Offset) {
}
void cSDDisplayMenu::SetEvent(const cEvent *Event) {
if (view)
if (view) {
if (view->MenuCat() != mcEvent)
view->SetSubView(mcEvent);
view->SetEvent(Event);
}
}
void cSDDisplayMenu::SetRecording(const cRecording *Recording) {
if (view)
if (view) {
if (view->MenuCat() != mcRecordingInfo)
view->SetSubView(mcRecordingInfo);
view->SetRecording(Recording);
}
}
void cSDDisplayMenu::SetText(const char *Text, bool FixedFont) {
if (view)
if (view) {
if (view->MenuCat() != mcText)
view->SetSubView(mcText);
view->SetText(Text);
}
}
bool cSDDisplayMenu::SetPluginText(skindesignerapi::cTokenContainer *tk) {
@ -171,4 +180,4 @@ void cSDDisplayMenu::SetCurrentRecording(void) {
return;
}
view->SetCurrentRecording(recording->FileName());
}
}

View File

@ -23,7 +23,8 @@ public:
virtual void SetTitle(const char *Title);
virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
virtual void SetMessage(eMessageType Type, const char *Text);
virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch);
virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch, bool TimerActive);
virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch) { return SetItemEvent(Event, Index, Current, Selectable, Channel, WithDate, TimerMatch, true); }
virtual bool SetItemTimer(const cTimer *Timer, int Index, bool Current, bool Selectable);
virtual bool SetItemChannel(const cChannel *Channel, int Index, bool Current, bool Selectable, bool WithProvider);
virtual bool SetItemRecording(const cRecording *Recording, int Index, bool Current, bool Selectable, int Level, int Total, int New);

View File

@ -1,7 +1,6 @@
#include "displayreplay.h"
cSDDisplayReplay::cSDDisplayReplay(cViewReplay *replayView, bool ModeOnly) {
init = true;
view = replayView;
ok = view->Init();
if (!ok)
@ -16,15 +15,12 @@ cSDDisplayReplay::~cSDDisplayReplay() {
void cSDDisplayReplay::SetRecording(const cRecording *Recording) {
if (ok) {
view->SetRecording(Recording);
if (init) {
view->SetRecordingLength(Recording->LengthInSeconds());
SetTimeShiftValues(Recording);
init = false;
}
}
}
void cSDDisplayReplay::SetTitle(const char *Title) {
if (!ok)
return;
view->SetTitle(Title);
}
@ -49,7 +45,9 @@ void cSDDisplayReplay::SetMode(bool Play, bool Forward, int Speed) {
void cSDDisplayReplay::SetProgress(int Current, int Total) {
if (ok) {
view->SetProgressbar(Current, Total);
view->SetMarks(marks, Current, Total);
if (marks)
view->SetMarks(marks, Current, Total);
view->SetTimeshiftTimes(Current, Total);
view->SetEndTime(Current, Total);
view->DelayOnPause();
}
@ -80,30 +78,3 @@ void cSDDisplayReplay::Flush(void) {
return;
view->Flush();
}
void cSDDisplayReplay::SetTimeShiftValues(const cRecording *recording) {
//check for instant recording
const char *recName = recording->Name();
if (recName && *recName == '@')
return;
bool isTimeShift = false;
#if APIVERSNUM >= 20101
int usage = recording->IsInUse();
if (usage & ruTimer)
isTimeShift = true;
#endif
if (!isTimeShift)
return;
const cRecordingInfo *recInfo = recording->Info();
if (!recInfo)
return;
const cEvent *event = recInfo->GetEvent();
if (!event)
return;
double fps = recording->FramesPerSecond();
time_t liveEventStop = event->EndTime();
time_t recordingStart = time(0) - recording->LengthInSeconds();
int framesTotal = (liveEventStop - recordingStart)*fps;
int recLength = liveEventStop - recordingStart;
view->SetTimeShift(framesTotal, recLength);
}

View File

@ -8,9 +8,7 @@
class cSDDisplayReplay : public cSkinDisplayReplay {
private:
bool ok;
bool init;
cViewReplay *view;
void SetTimeShiftValues(const cRecording *recording);
public:
cSDDisplayReplay(cViewReplay *replayView, bool ModeOnly);
virtual ~cSDDisplayReplay();

View File

@ -40,6 +40,12 @@
width CDATA #REQUIRED
height CDATA #REQUIRED
align (left|top|center|bottom|right) #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
menuitemwidth CDATA #IMPLIED
numlistelements CDATA #REQUIRED
orientation CDATA #REQUIRED

View File

@ -4,7 +4,10 @@
<!ELEMENT displaychannel (background | channelinfo | epginfo | progressbar | progressbarback |
statusinfo | audioinfo | ecminfo | screenresolution | channelgroup |
signalquality | signalqualityback | devices | currentweather | scrapercontent |
signalquality | signalqualityback | devices | currentweather |
scrapercontent | channelhints | channeldetail | channellistdetail |
channellistback | channellist | grouplistback | grouplist |
groupchannellistback | groupchannellist | groupchannellistdetail |
datetime | time | message | customtokens)* >
<!ATTLIST displaychannel
x CDATA #REQUIRED
@ -220,6 +223,163 @@
condition CDATA #IMPLIED
>
<!ELEMENT channelhints (areacontainer|area|areascroll)*>
<!ATTLIST channelhints
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT channeldetail (areacontainer|area|areascroll)*>
<!ATTLIST channeldetail
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
clearondisplay CDATA #IMPLIED
>
<!ELEMENT channellistback (areacontainer|area|areascroll)*>
<!ATTLIST channellistback
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
clearondisplay CDATA #IMPLIED
>
<!ELEMENT grouplistback (areacontainer|area|areascroll)*>
<!ATTLIST grouplistback
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
clearondisplay CDATA #IMPLIED
>
<!ELEMENT groupchannellistback (areacontainer|area|areascroll)*>
<!ATTLIST groupchannellistback
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT channellist (listelement)>
<!ATTLIST channellist
x CDATA #REQUIRED
y CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
align (left|top|center|bottom|right) #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
numlistelements CDATA #REQUIRED
orientation CDATA #REQUIRED
condition CDATA #IMPLIED
button CDATA #IMPLIED
>
<!ELEMENT grouplist (listelement)>
<!ATTLIST grouplist
x CDATA #REQUIRED
y CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
align (left|top|center|bottom|right) #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
numlistelements CDATA #REQUIRED
orientation CDATA #REQUIRED
condition CDATA #IMPLIED
button CDATA #IMPLIED
>
<!ELEMENT groupchannellist (listelement)>
<!ATTLIST groupchannellist
x CDATA #REQUIRED
y CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
align (left|top|center|bottom|right) #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
numlistelements CDATA #REQUIRED
orientation CDATA #REQUIRED
condition CDATA #IMPLIED
>
<!ELEMENT listelement (areacontainer|area|areascroll)*>
<!ATTLIST listelement
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
debug CDATA #IMPLIED
>
<!ELEMENT channellistdetail (areacontainer|area|areascroll)*>
<!ATTLIST channellistdetail
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT groupchannellistdetail (areacontainer|area|areascroll)*>
<!ATTLIST groupchannellistdetail
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT datetime (areacontainer|area|areascroll)*>
<!ATTLIST datetime
delay CDATA #IMPLIED

View File

@ -2,7 +2,7 @@
<!ENTITY % functions SYSTEM "functions.dtd">
<!ELEMENT displaymenu (background,header,datetime,time*,message,sortmode*,colorbuttons,scrollbar*,
<!ELEMENT displaymenu (background,header,datetime,time*,vdrstatus*,message,sortmode*,colorbuttons,scrollbar*,
menudefault,menumain*,menusetup*,menuschedules*,
menutimers*,menuchannels*,menurecordings*,
menudetailedepg,menudetailedrecording,
@ -218,6 +218,20 @@
condition CDATA #IMPLIED
>
<!ELEMENT vdrstatus (areacontainer|area|areascroll)*>
<!ATTLIST vdrstatus
delay CDATA #IMPLIED
orientation CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT currentschedule (areacontainer|area|areascroll)*>
<!ATTLIST currentschedule
delay CDATA #IMPLIED
@ -316,7 +330,7 @@
>
<!ELEMENT menumain (background | header | datetime | time | colorbuttons | scrollbar | sortmode | timers |
discusage | devices | systemload | systemmemory | vdrstatistics | temperatures | currentschedule |
discusage | devices | systemload | systemmemory | vdrstatistics | vdrstatus | temperatures | currentschedule |
currentweather | lastrecordings | customtokens | menuitems)*>
<!ATTLIST menumain
x CDATA #REQUIRED
@ -468,6 +482,8 @@
<!ELEMENT listelement (areacontainer|area|areascroll)*>
<!ATTLIST listelement
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
debug CDATA #IMPLIED
>
@ -499,4 +515,4 @@
debug (true|false) #IMPLIED
>
%functions;
%functions;

View File

@ -117,6 +117,8 @@
<!ELEMENT listelement (areacontainer|area|areascroll)*>
<!ATTLIST listelement
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
debug CDATA #IMPLIED
>
@ -125,6 +127,11 @@
condition CDATA #IMPLIED
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
>

View File

@ -4,7 +4,7 @@
<!ELEMENT displayreplay (background | backgroundmodeonly |datetime | time |
scrapercontent | currentweather | rectitle | recinfo | currenttime |
totaltime | endtime | progressbar | cutmarks | controlicons |
totaltime | timeshifttimes | endtime | progressbar | cutmarks | controlicons |
controliconsmodeonly | progressmodeonly | jump | message | onpause |
onpausemodeonly | customtokens)*>
<!ATTLIST displayreplay
@ -153,6 +153,19 @@
condition CDATA #IMPLIED
>
<!ELEMENT timeshifttimes (areacontainer|area|areascroll)*>
<!ATTLIST timeshifttimes
delay CDATA #IMPLIED
fadetime CDATA #IMPLIED
shifttime CDATA #IMPLIED
shifttype CDATA #IMPLIED
shiftmode CDATA #IMPLIED
startx CDATA #IMPLIED
starty CDATA #IMPLIED
debug CDATA #IMPLIED
condition CDATA #IMPLIED
>
<!ELEMENT endtime (areacontainer|area|areascroll)*>
<!ATTLIST endtime
delay CDATA #IMPLIED
@ -289,4 +302,4 @@
condition CDATA #IMPLIED
>
%functions;
%functions;

View File

@ -18,6 +18,7 @@
transparency CDATA #IMPLIED
condition CDATA #IMPLIED
background (true|false) #IMPLIED
indicator (true|false) #IMPLIED
debug (true|false) #IMPLIED
>
@ -50,8 +51,8 @@
<!ELEMENT loop (drawtext|drawtextbox|drawtextvertical|drawimage|drawrectangle|drawellipse|drawslope)+>
<!ATTLIST loop
x CDATA #REQUIRED
y CDATA #REQUIRED
x CDATA #IMPLIED
y CDATA #IMPLIED
width CDATA #IMPLIED
height CDATA #IMPLIED
columnwidth CDATA #IMPLIED
@ -60,6 +61,7 @@
orientation (horizontal|vertical|absolute) #REQUIRED
overflow (linewrap|cut) #IMPLIED
maxitems CDATA #IMPLIED
valign (top|bottom) #IMPLIED
debug (true|false) #IMPLIED
>

View File

@ -13,7 +13,7 @@
<!ELEMENT parameter (#PCDATA)>
<!ATTLIST parameter
name NMTOKEN #REQUIRED
type (int|bool|string) #REQUIRED
type (int|bool|string|separator) #REQUIRED
min NMTOKEN #IMPLIED
max NMTOKEN #IMPLIED
displaytext CDATA #REQUIRED

View File

@ -19,7 +19,7 @@ bool cExtRecInfo::Parse(void) {
}
StripXmlTag(mediaInfoXml, resWidth, "res_width");
StripXmlTag(mediaInfoXml, resHeight, "res_height");
resString = GetScreenResolutionString(resWidth, resHeight, &isHD);
resString = GetScreenResolutionString(resWidth, resHeight, &isHD, &isUHD);
StripXmlTag(mediaInfoXml, aspectratio, "aspectratio");
isWideScreen = !aspectratio.compare("16:9");
StripXmlTag(mediaInfoXml, codec, "codec");

View File

@ -23,6 +23,7 @@ public:
int resHeight;
string resString;
bool isHD;
bool isUHD;
string aspectratio;
bool isWideScreen;
string codec;
@ -33,4 +34,4 @@ public:
vector< tAudioTrack > tracks;
};
#endif // __EXTRECINFO_H
#endif // __EXTRECINFO_H

257
extensions/globaltimers.c Normal file
View File

@ -0,0 +1,257 @@
#include "globaltimers.h"
#include "../services/epgsearch.h"
#include "../services/remotetimers.h"
#include "../services/epgtimer.h"
static int CompareTimers(const void *a, const void *b) {
return (*(const cTimer **)a)->Compare(**(const cTimer **)b);
}
bool cGlobalTimers::initial = true;
cRemoteTimerRefresh *cGlobalTimers::remoteTimerRefresh = NULL;
cGlobalTimers::cGlobalTimers(void) : cVector<const cTimer*>(0) {
pEpg2Vdr = cPluginManager::GetPlugin("epg2vdr");
pRemoteTimers = cPluginManager::GetPlugin("remotetimers");
pEpgSearch = cPluginManager::GetPlugin("epgsearch");
localTimer = NULL;
isEpg2VdrTimers = false;
}
cGlobalTimers::~cGlobalTimers(void) {
if (localTimer) {
delete[] localTimer;
}
ClearTimers();
}
void cGlobalTimers::LoadTimers(void) {
isEpg2VdrTimers = false;
bool epg2vdrOk = false;
if (pEpg2Vdr) {
epg2vdrOk = SetEpg2VdrTimers();
}
if (!epg2vdrOk) {
SetLocalTimers();
if (pRemoteTimers) {
SetRemoteTimers(initial);
}
}
initial = false;
}
void cGlobalTimers::SortTimers(void) {
Sort(CompareTimers);
}
void cGlobalTimers::MarkLocalTimers(void) {
if (isEpg2VdrTimers)
return;
if (localTimer) {
delete[] localTimer;
localTimer = NULL;
}
const cTimers* timers;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
{
LOCK_TIMERS_READ;
timers = Timers;
}
#else
timers = &Timers;
#endif
int numTimers = Size();
if (numTimers > 0) {
localTimer = new bool[numTimers];
for (int i=0; i < numTimers; i++) {
if (!pRemoteTimers) {
localTimer[i] = true;
} else {
localTimer[i] = false;
for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer == At(i)) {
localTimer[i] = true;
break;
}
}
}
}
}
}
void cGlobalTimers::SetLocalTimers(void) {
const cTimers* timers;
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
{
LOCK_TIMERS_READ;
timers = Timers;
}
#else
timers = &Timers;
#endif
for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer && Timer->HasFlags(tfActive))
Append(Timer);
}
}
void cGlobalTimers::SetRemoteTimers(bool initial) {
if (initial) {
cString errorMsg;
pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg);
}
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock;
const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
#endif
cTimer* remoteTimer = NULL;
while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) {
remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current
if (remoteTimer->HasFlags(tfActive))
Append(remoteTimer);
}
}
bool cGlobalTimers::SetEpg2VdrTimers(void) {
bool ok = false;
cEpgTimer_Service_V1 data;
if (pEpg2Vdr->Service(EPG2VDR_TIMER_SERVICE, &data)) {
for (std::list<cEpgTimer_Interface_V1*>::iterator it = data.epgTimers.begin(); it != data.epgTimers.end(); ++it) {
ok = true;
isEpg2VdrTimers = true;
if ((*it)->HasFlags(tfActive)) {
Append(*it);
}
}
}
return ok;
}
int cGlobalTimers::NumTimerConfilicts(void) {
int numConflicts = 0;
if (pEpgSearch) {
Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0;
if (serviceData) {
serviceData->nextConflict = 0;
serviceData->relevantConflicts = 0;
serviceData->totalConflicts = 0;
pEpgSearch->Service("Epgsearch-lastconflictinfo-v1.0", serviceData);
if (serviceData->relevantConflicts > 0) {
numConflicts = serviceData->relevantConflicts;
}
delete serviceData;
}
}
return numConflicts;
}
bool cGlobalTimers::IsRemoteTimer(int i) {
if (isEpg2VdrTimers) {
cEpgTimer_Interface_V1* epgTimer;
if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i)))
return !epgTimer->isLocal();
else
return false;
}
if (!localTimer)
return true;
if (i >= Size())
return true;
return !(localTimer[i]);
}
const char* cGlobalTimers::RemoteHost(int i) {
if (isEpg2VdrTimers) {
cEpgTimer_Interface_V1* epgTimer;
if (epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)At(i)))
return epgTimer->VdrName();
}
return "";
}
bool cGlobalTimers::IsRecording(const cRecording *rec) {
if (!rec || !rec->Name())
return false;
std::string recName = rec->Name();
time_t recstart = rec->Start();
int size = Size();
for (int i=0; i<size; i++) {
const cTimer *t = At(i);
const char *timerFile = t->File();
if (!t->Matches() || !timerFile)
continue;
if (recName.find(timerFile) != std::string::npos) {
time_t timerstart = t->StartTime();
if (recstart == timerstart)
return true;
}
}
return false;
}
void cGlobalTimers::ClearTimers(void) {
if (isEpg2VdrTimers) {
int size = Size();
for (int i=0; i<size; i++) {
delete At(i);
}
}
Clear();
}
void cGlobalTimers::StartRefreshThread(void) {
if (remoteTimerRefresh == NULL) {
remoteTimerRefresh = new cRemoteTimerRefresh();
}
}
void cGlobalTimers::StopRefreshThread(void) {
if (!remoteTimerRefresh)
return;
delete remoteTimerRefresh;
remoteTimerRefresh = NULL;
initial = true;
}
/*************************************************************************
* cRemoteTimerRefresh
*************************************************************************/
cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") {
pRemoteTimers = cPluginManager::GetPlugin("remotetimers");
if (pRemoteTimers)
Start();
}
cRemoteTimerRefresh::~cRemoteTimerRefresh(void) {
Cancel(-1);
while (Active())
cCondWait::SleepMs(10);
}
void cRemoteTimerRefresh::Action(void) {
#define REFESH_INTERVALL_MS 30000
int sleepSlice = 1000;
int slept = 0;
while (Running()) {
while (Running() && slept < REFESH_INTERVALL_MS) {
cCondWait::SleepMs(sleepSlice);
slept += sleepSlice;
}
slept = 0;
// make sure that no timer is currently being edited
if (!cOsd::IsOpen() && Running()) {
cString errorMsg;
pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg);
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_WRITE;
Timers->SetModified();
#else
Timers.SetModified();
#endif
}
}
}

45
extensions/globaltimers.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef __GLOBALTIMERS_H
#define __GLOBALTIMERS_H
#include <vdr/timers.h>
#include <vdr/plugin.h>
class cRemoteTimerRefresh;
class cGlobalTimers : public cVector<const cTimer *> {
private:
static bool initial;
static cRemoteTimerRefresh *remoteTimerRefresh;
bool *localTimer;
cPlugin *pEpg2Vdr;
cPlugin *pRemoteTimers;
cPlugin *pEpgSearch;
bool isEpg2VdrTimers;
void SetLocalTimers(void);
void SetRemoteTimers(bool initial);
bool SetEpg2VdrTimers(void);
public:
cGlobalTimers(void);
virtual ~cGlobalTimers(void);
void LoadTimers(void);
void SortTimers(void);
void MarkLocalTimers(void);
int NumTimerConfilicts(void);
bool IsRemoteTimer(int i);
const char* RemoteHost(int i);
bool IsRecording(const cRecording *rec);
void ClearTimers(void);
static void StartRefreshThread(void);
static void StopRefreshThread(void);
};
class cRemoteTimerRefresh: public cThread {
private:
cPlugin* pRemoteTimers;
protected:
virtual void Action(void);
public:
cRemoteTimerRefresh(void);
virtual ~cRemoteTimerRefresh(void);
};
#endif //__GLOBALTIMERS_H

View File

@ -198,29 +198,43 @@ string GetTimeString(int seconds) {
//View Helpers
string GetScreenResolutionString(int width, int height, bool *isHD) {
string GetScreenResolutionString(int width, int height, bool *isHD, bool *isUHD) {
// TODO: try to get more information from information sources about interlace/progressive
// cDevice::PrimaryDevice()->GetVideoSize is NOT providing enough information
*isHD = false; // default
*isUHD = false; // default
string name = "";
switch (width) {
case 1920:
case 1440:
name = "hd1080i";
switch (height) {
case 4320: // 7680 x 4320 = 8K UHD
name = "uhd4320p";
*isHD = true;
*isUHD = true;
break;
case 2160: // 3840 x 2160 = 4K UHD
name = "uhd2160p";
*isHD = true;
*isUHD = true;
break;
case 1440: // 2560 x 1440 = QHD
name = "hd1440p";
*isHD = true;
break;
case 1280:
if (height == 720)
name = "hd720p";
else
name = "hd1080i";
case 1080:
name = "hd1080i"; // 'i' is default, 'p' can't be detected currently
*isHD = true;
break;
case 720:
name = "sd576i";
name = "hd720p"; // 'i' is not defined in standards
*isHD = true;
break;
case 544:
name = "sd480i";
case 576:
name = "sd576i"; // assumed 'i'
break;
case 480:
name = "sd480i"; // assumed 'i'
break;
default:
name = "sd576i";
name = "unknown";
break;
}
return name;

View File

@ -44,7 +44,7 @@ public:
string GetTimeString(int seconds);
string GetScreenResolutionString(int width, int height, bool *isHD);
string GetScreenResolutionString(int width, int height, bool *isHD, bool *isUHD);
string GetScreenAspectString(double aspect, bool *isWideScreen);
#endif // __HELPERS_H

View File

@ -346,6 +346,11 @@ bool cImageCache::MenuIconExists(string name) {
if (FileExists(*iconSkinPath, name, "png")) {
return true;
}
//finally check svg templates
cString iconTemplatePath = cString::sprintf("%smenuicons/", svgTemplatePath.c_str());
if (FileExists(*iconTemplatePath, name, "svg")) {
return true;
}
return false;
}
@ -433,7 +438,7 @@ bool cImageCache::LoadIcon(eImageType type, string name) {
return LoadImage(*subIconSkinPath, name, "png");
//and finally check if a svg template exists
cSVGTemplate svgTemplate(name, svgTemplatePath);
cSVGTemplate svgTemplate(name, *subdir, svgTemplatePath);
if (!svgTemplate.Exists())
return false;
svgTemplate.ReadTemplate();
@ -484,7 +489,7 @@ bool cImageCache::LoadSkinpart(string name) {
return LoadImage(skinPartsPathSkin.c_str(), name, "png");
//check if a svg template exists
cSVGTemplate svgTemplate(name, svgTemplatePath);
cSVGTemplate svgTemplate(name, "skinparts", svgTemplatePath);
if (!svgTemplate.Exists())
return false;
svgTemplate.ReadTemplate();

View File

@ -178,14 +178,22 @@ cImageImporterSVG::cImageImporterSVG() {
cImageImporterSVG::~cImageImporterSVG() {
if (handle) {
#if LIBRSVG_CHECK_VERSION (2, 46, 0)
// rsvg_handle_close is deprecated since version 2.46 and looks like even not required if used with rsvg_handle_new_from_file
#else
rsvg_handle_close(handle, NULL);
#endif
g_object_unref(handle);
}
}
bool cImageImporterSVG::LoadImage(const char *path) {
if (handle) {
#if LIBRSVG_CHECK_VERSION (2, 46, 0)
// rsvg_handle_close is deprecated since version 2.46 and looks like even not required if used with rsvg_handle_new_from_file
#else
rsvg_handle_close(handle, NULL);
#endif
g_object_unref(handle);
}
@ -405,21 +413,37 @@ void cImageImporterJPG::GetImageSize(int &width, int &height) {
// SVG Template class
//
cSVGTemplate::cSVGTemplate(string imageName, string templatePath) {
cSVGTemplate::cSVGTemplate(string imageName, string imagePath, string templatePath) {
this->imageName = imageName;
this->imagePath = imagePath;
this->templatePath = templatePath;
filePath = CreateImagePath();
startTokenColor = "{sdcol(";
startTokenOpac = "{sdopac(";
endToken = ")}";
filePath = templatePath;
filePath += imageName + ".svg";
}
cSVGTemplate::~cSVGTemplate(void) {
}
string cSVGTemplate::CreateImagePath(void) {
//check if imageName is a path
if (imageName.find("/") != string::npos) {
splitstring s(imageName.c_str());
vector<string> flds = s.split('/', 1);
int num = flds.size() - 1;
for (int i=0; i < num; i++) {
imagePath = *cString::sprintf("%s/%s", imagePath.c_str(), flds[i].c_str());
}
imageName = flds[num];
}
string path = templatePath;
path += imagePath + "/" + imageName + ".svg";
return path;
}
bool cSVGTemplate::Exists(void) {
return FileExists(templatePath, imageName, "svg");
return FileExists(filePath);
}
void cSVGTemplate::ReadTemplate(void) {
@ -464,7 +488,7 @@ bool cSVGTemplate::ParseTemplate(void) {
}
string cSVGTemplate::WriteImage(void) {
string tempPath = *cString::sprintf("/tmp/skindesigner/svg/%s/%s/", Setup.OSDSkin, Setup.OSDTheme);
string tempPath = *cString::sprintf("/tmp/skindesigner/svg/%s/%s/%s/", Setup.OSDSkin, Setup.OSDTheme, imagePath.c_str());
CreateFolder(tempPath);
string fileName = tempPath + imageName + ".svg";
ofstream tmpimg;
@ -505,3 +529,5 @@ void cSVGTemplate::ReplaceTokens(string &line, size_t tokenStart, size_t tokenEn
std::replace( svgAlpha.begin(), svgAlpha.end(), ',', '.');
line.replace(hitAlpha, hitAlphaEnd - hitAlpha + 2, svgAlpha);
}
// vim: ts=4 sw=4 et

View File

@ -95,16 +95,18 @@ public:
class cSVGTemplate {
private:
string imageName;
string imagePath;
string templatePath;
string filePath;
string startTokenColor;
string startTokenOpac;
string endToken;
vector<string> svgTemplate;
string CreateImagePath(void);
string GetColorName(string line, size_t tokenStart, size_t tokenEnd);
void ReplaceTokens(string &line, size_t tokenStart, size_t tokenEnd, tColor color);
public:
cSVGTemplate(string imageName, string templatePath);
cSVGTemplate(string imageName, string imagePath, string templatePath);
virtual ~cSVGTemplate(void);
bool Exists(void);
void ReadTemplate(void);

View File

@ -33,6 +33,9 @@ void cSkinSetupParameter::Debug(void) {
sType = "int";
else if (type == sptString)
sType = "string";
else if (type == sptSeparator)
sType = "separator";
dsyslog("skindesigner: name \"%s\", type %s, displayText \"%s\", Value: %d", name.c_str(), sType.c_str(), displayText.c_str(), value);
if (type == sptInt)
dsyslog("skindesigner: min %d, max %d", min, max);
@ -224,7 +227,7 @@ void cSkinSetup::SubMenuDone(void) {
}
void cSkinSetup::SetParameter(string type, string name, string displayText, string helpText, string min, string max, string value, string options) {
if (!type.size() || !name.size() || !displayText.size() || !value.size()) {
if (!type.size() || !name.size() || !displayText.size()) {
esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str());
return;
}
@ -235,6 +238,8 @@ void cSkinSetup::SetParameter(string type, string name, string displayText, stri
paramType = sptBool;
} else if (!type.compare("string")) {
paramType = sptString;
} else if (!type.compare("separator")) {
paramType = sptSeparator;
}
if (paramType == sptUnknown) {
esyslog("skindesigner: invalid setup parameter for skin %s", skin.c_str());
@ -266,7 +271,7 @@ void cSkinSetup::AddToGlobals(cGlobals *globals) {
globals->AddString(param->name, value);
string intName = "index" + param->name;
globals->AddInt(intName, param->value);
} else {
} else if (param->type == sptInt || param->type == sptBool) {
globals->AddInt(param->name, param->value);
}
}

View File

@ -16,6 +16,7 @@ enum eSetupParameterType {
sptInt,
sptBool,
sptString,
sptSeparator,
sptUnknown
};

View File

@ -1,134 +0,0 @@
#include "timers.h"
#include "../services/epgsearch.h"
#include "../services/remotetimers.h"
static int CompareTimers(const void *a, const void *b) {
return (*(const cTimer **)a)->Compare(**(const cTimer **)b);
}
cGlobalSortedTimers::cGlobalSortedTimers(int timerCount, bool forceRefresh) : cVector<const cTimer*>(timerCount) {
static bool initial = true;
static cRemoteTimerRefresh *remoteTimerRefresh = NULL;
localTimer = NULL;
if (forceRefresh)
initial = true;
//check if remotetimers plugin is available
static cPlugin* pRemoteTimers = cPluginManager::GetPlugin("remotetimers");
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_READ;
LOCK_SCHEDULES_READ;
const cTimers* timers = Timers;
const cSchedules* schedules = Schedules;
#else
const cTimers* timers = &Timers;
cSchedulesLock schedulesLock;
const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock);
#endif
if (pRemoteTimers && initial) {
cString errorMsg;
pRemoteTimers->Service("RemoteTimers::RefreshTimers-v1.0", &errorMsg);
initial = false;
}
for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer->HasFlags(tfActive))
Append(Timer);
}
//if remotetimers plugin is available, take timers also from him
if (pRemoteTimers) {
cTimer* remoteTimer = NULL;
while (pRemoteTimers->Service("RemoteTimers::ForEach-v1.0", &remoteTimer) && remoteTimer != NULL) {
remoteTimer->SetEventFromSchedule(schedules); // make sure the event is current
if (remoteTimer->HasFlags(tfActive))
Append(remoteTimer);
}
}
Sort(CompareTimers);
int numTimers = Size();
if (numTimers > 0) {
localTimer = new bool[numTimers];
for (int i=0; i < numTimers; i++) {
if (!pRemoteTimers) {
localTimer[i] = true;
} else {
localTimer[i] = false;
for (const cTimer *Timer = timers->First(); Timer; Timer = timers->Next(Timer)) {
if (Timer == At(i)) {
localTimer[i] = true;
break;
}
}
}
}
}
if (pRemoteTimers && (remoteTimerRefresh == NULL))
remoteTimerRefresh = new cRemoteTimerRefresh();
}
cGlobalSortedTimers::~cGlobalSortedTimers(void) {
if (localTimer) {
delete[] localTimer;
}
}
bool cGlobalSortedTimers::IsRemoteTimer(int i) {
if (!localTimer)
return true;
if (i >= Size())
return true;
return !(localTimer[i]);
}
int cGlobalSortedTimers::NumTimerConfilicts(void) {
int numConflicts = 0;
cPlugin *p = cPluginManager::GetPlugin("epgsearch");
if (p) {
Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0;
if (serviceData) {
serviceData->nextConflict = 0;
serviceData->relevantConflicts = 0;
serviceData->totalConflicts = 0;
p->Service("Epgsearch-lastconflictinfo-v1.0", serviceData);
if (serviceData->relevantConflicts > 0) {
numConflicts = serviceData->relevantConflicts;
}
delete serviceData;
}
}
return numConflicts;
}
cRemoteTimerRefresh::cRemoteTimerRefresh(): cThread("skindesigner: RemoteTimers::RefreshTimers") {
Start();
}
cRemoteTimerRefresh::~cRemoteTimerRefresh(void) {
Cancel(-1);
while (Active())
cCondWait::SleepMs(10);
}
void cRemoteTimerRefresh::Action(void) {
#define REFESH_INTERVALL_MS 30000
while (Running()) {
cCondWait::SleepMs(REFESH_INTERVALL_MS);
// make sure that no timer is currently being edited
if (!cOsd::IsOpen()) {
cGlobalSortedTimers(true);
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
LOCK_TIMERS_WRITE;
Timers->SetModified();
#else
Timers.SetModified();
#endif
}
}
}

View File

@ -1,24 +0,0 @@
#ifndef __NOPACITY_TIMERS_H
#define __NOPACITY_TIMERS_H
#include <vdr/timers.h>
#include <vdr/plugin.h>
class cGlobalSortedTimers : public cVector<const cTimer *> {
private:
bool *localTimer;
public:
cGlobalSortedTimers(int timerCount, bool forceRefresh = false);
virtual ~cGlobalSortedTimers(void);
bool IsRemoteTimer(int i);
int NumTimerConfilicts(void);
};
class cRemoteTimerRefresh: public cThread {
protected:
virtual void Action(void);
public:
cRemoteTimerRefresh(void);
virtual ~cRemoteTimerRefresh(void);
};
#endif //__NOPACITY_TIMERS_H

View File

@ -3,7 +3,7 @@
NAME = skindesignerapi
LIBNAME = lib$(NAME)
MAJOR = 0
MINOR = 1.0
MINOR = 1.2
VERSION = $(MAJOR).$(MINOR)
SONAME = $(LIBNAME).so.$(MAJOR)
@ -32,7 +32,8 @@ OBJS = $(SRCS:.c=.o)
all: ${TARGET_LIB} ${LIBNAME}.pc
%.o: %.c
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
@echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
# Dependencies:
@ -46,7 +47,8 @@ $(DEPFILE): Makefile
# The main lib
$(TARGET_LIB): $(OBJS)
$(CXX) ${LDFLAGS} -o $@ $^
@echo LD $@
$(Q)$(CXX) ${LDFLAGS} -o $@ $^
if [ -n "$(LCLBLD)" ] ; then \
ln -s $(TARGET_LIB) $(LIBNAME).so ; \
ln -s $(TARGET_LIB) $(SONAME) ; \

View File

@ -22,7 +22,7 @@ private:
//token containers
char **stringTokens;
int *intTokens;
vector<char***>loopTokens;
vector<char***> loopTokens;
//mapping id --> name
string *stNames;
string *itNames;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-skindesigner 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2016-01-20 18:31+0100\n"
"POT-Creation-Date: 2020-07-15 13:04+0200\n"
"PO-Revision-Date: 2014-09-27 11:02+0200\n"
"Last-Translator: Louis Braun <louis.braun@gmx.de>\n"
"Language-Team: \n"
@ -45,8 +45,11 @@ msgstr "eines nach dem anderen"
msgid "at one go"
msgstr "alle auf einmal"
msgid "Updating Skinrepositories"
msgstr "Aktualisiere Skinrepositories"
msgid "Downloading Skin Screenshots..."
msgstr ""
msgstr "Lade Skin Screenshots..."
msgid "Install Skin"
msgstr "Installiere Skin"
@ -69,7 +72,7 @@ msgstr "oder höher"
msgid "needed"
msgstr "benötigt"
msgid "No Git Repsoitory available"
msgid "No Git Repository available"
msgstr "Kein Git Repository verfügbar"
msgid "Skin is running and can't be deleted"
@ -84,12 +87,18 @@ msgstr "Skin gelöscht"
msgid "Plugin Setup"
msgstr ""
msgid "Frames per Second to display animations"
msgstr "Frames pro Sekunde für Animationen"
msgid "Maximum number of custom tokens"
msgstr "Maximale Anzahl Custom Tokens"
msgid "Reruns"
msgstr "Wiederholungen"
msgid "Use Subtitle for reruns"
msgstr "Untertitel vergleichen"
msgid "Maximum number of reruns to display"
msgstr "Anzahl anzuzeigender Wiederholungen"
@ -165,6 +174,9 @@ msgstr "Skin Vorschau"
msgid "Help"
msgstr "Hilfe"
msgid "Preview"
msgstr ""
msgid "Author"
msgstr "Autor"
@ -173,4 +185,3 @@ msgstr "Benutze Schriftarten"
msgid "Supported Plugins"
msgstr "Unterstützte Plugins"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-skindesigner 0.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2016-01-20 18:31+0100\n"
"POT-Creation-Date: 2020-07-15 13:04+0200\n"
"PO-Revision-Date: 2015-01-25 01:25+0200\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish\n"
@ -16,28 +16,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
msgid "Skin successfully installed"
msgstr ""
msgstr "Ulkoasun asennus onnistui"
msgid "Skin NOT successfully installed"
msgstr ""
msgstr "Ulkoasun asennus epäonnistui"
msgid "Timeout"
msgstr ""
msgstr "Aikakatkaisu"
msgid "Installing Skin"
msgstr ""
msgstr "Asennetaan ulkoasua"
msgid "sec"
msgstr ""
msgstr "s"
msgid "Skin successfully updated"
msgstr ""
msgstr "Ulkoasu päivitetty onnistuneesti"
msgid "Skin already up to date"
msgstr ""
msgstr "Ulkoasu on ajantasalla"
msgid "Updating Skin from Git"
msgstr ""
msgstr "Päivitetään ulkoasua git-projektista"
msgid "after one another"
msgstr "yksi kerrallaan"
@ -45,53 +45,62 @@ msgstr "yksi kerrallaan"
msgid "at one go"
msgstr "kaikki kerralla"
msgid "Downloading Skin Screenshots..."
msgid "Updating Skinrepositories"
msgstr ""
msgid "Downloading Skin Screenshots..."
msgstr "Ladataan kuvakaappauksia ulkoasusta..."
msgid "Install Skin"
msgstr ""
msgstr "Asenna ulkoasu"
msgid "Update"
msgstr ""
msgstr "Päivitä"
msgid "Delete Skin"
msgstr ""
msgstr "Poista ulkoasu"
msgid "Skin Designer"
msgstr "Skin Designer -ulkoasu"
msgstr "Skin Designer -ulkoasut"
msgid "version"
msgstr ""
msgstr "versio"
msgid "or higher"
msgstr ""
msgstr "tai uudempi"
msgid "needed"
msgstr ""
msgstr "vaaditaan"
msgid "No Git Repsoitory available"
msgstr ""
msgid "No Git Repository available"
msgstr "Git-projekti ei käytettävissä"
msgid "Skin is running and can't be deleted"
msgstr ""
msgstr "Käytössä olevaa ulkoasua ei voida poistaa"
msgid "Really delete skin"
msgstr ""
msgstr "Poistetaanko ulkoasu"
msgid "Skin deleted"
msgstr ""
msgstr "Ulkoasu poistettu"
msgid "Plugin Setup"
msgstr "Yleiset"
msgid "Maximum number of custom tokens"
msgid "Frames per Second to display animations"
msgstr ""
msgid "Maximum number of custom tokens"
msgstr "Mukautettujen tokenien maksimimäärä"
msgid "Reruns"
msgstr "Uusinnat"
msgid "Use Subtitle for reruns"
msgstr ""
msgid "Maximum number of reruns to display"
msgstr "Maksimissaan näytettävät uusinnat"
msgstr "Näytettävien uusintojen maksimimäärä"
msgid "Minimum timely distance of rerun (in hours)"
msgstr "Minimikesto uusintojen välillä [h]"
@ -103,22 +112,22 @@ msgid "no limit"
msgstr "ei rajoitusta"
msgid "Image Loading"
msgstr "Kuvat"
msgstr "Kuvien lataus"
msgid "Debug Image Loading"
msgstr "Debuggaa kuvien latausta"
msgid "Cache icons, skinparts and logos at start"
msgstr ""
msgstr "Täytä välimuisti käynnistyessä"
msgid "Limit Channel Logo Cache"
msgstr "Rajoita kanavalogojen välimuistia"
msgid "Number to cache initially (per size)"
msgstr "Oletuksena välimuistissa pidettävät logot"
msgstr "Oletuksena välimuistissa pidettävät kuvat"
msgid "Number to cache in maximum"
msgstr "Maksimissaan välimuistissa pidettävät logot"
msgstr "Maksimissaan välimuistissa pidettävät kuvat"
msgid "Cache Statistics"
msgstr "Välimuisti"
@ -133,13 +142,13 @@ msgid "size"
msgstr "koko"
msgid "MB"
msgstr ""
msgstr "MB"
msgid "int. memory"
msgstr ""
msgstr "sisäinen muisti"
msgid "high level memory"
msgstr ""
msgstr "korkean tason muisti"
msgid "logos"
msgstr "logo(a)"
@ -157,25 +166,22 @@ msgid "has no setup"
msgstr "ei asetuksia"
msgid "Install new skins"
msgstr ""
msgstr "Asenna uusia ulkoasuja"
msgid "Preview Skin"
msgstr ""
msgstr "Esikatsele ulkoasu"
msgid "Help"
msgstr ""
msgstr "Opaste"
msgid "Preview"
msgstr "Esikatsele"
msgid "Author"
msgstr ""
msgstr "Tekijä"
msgid "Used Fonts"
msgstr ""
msgstr "Käytetyt kirjasimet"
msgid "Supported Plugins"
msgstr ""
#~ msgid "byte"
#~ msgstr "tavu(a)"
#~ msgid "Menu Item display method"
#~ msgstr "Valikkorivien esitystapa"
msgstr "Tuetut laajennokset"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-skindesigner 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-08-14 17:02+0200\n"
"POT-Creation-Date: 2020-07-15 13:04+0200\n"
"PO-Revision-Date: 2015-08-09 11:02+0200\n"
"Last-Translator: fiveten_59\n"
"Language-Team: Italian\n"
@ -45,6 +45,9 @@ msgstr "in serie"
msgid "at one go"
msgstr "in una volta sola"
msgid "Updating Skinrepositories"
msgstr ""
msgid "Downloading Skin Screenshots..."
msgstr "Downloading Skin Screenshots..."
@ -69,7 +72,7 @@ msgstr "o maggiore"
msgid "needed"
msgstr "necessario"
msgid "No Git Repsoitory available"
msgid "No Git Repository available"
msgstr "Nessun Git Repository disponibile"
msgid "Skin is running and can't be deleted"
@ -84,12 +87,18 @@ msgstr "Skin eliminata"
msgid "Plugin Setup"
msgstr "Plugin Setup"
msgid "Frames per Second to display animations"
msgstr ""
msgid "Maximum number of custom tokens"
msgstr "Numero massimo di token personalizzati"
msgid "Reruns"
msgstr "Riavvii"
msgid "Use Subtitle for reruns"
msgstr ""
msgid "Maximum number of reruns to display"
msgstr "NUmero massimo di riavvii da visualizzare"
@ -165,6 +174,9 @@ msgstr "Anteprima Skin"
msgid "Help"
msgstr "Aiuto"
msgid "Preview"
msgstr ""
msgid "Author"
msgstr "Autore"

View File

@ -7,11 +7,8 @@ OUTPUTFLDR="/tmp/skindesigner/"
mkdir -p ${OUTPUTFLDR}
# there can be 2 files, vdrcpu and vdrmem
rm -f ${OUTPUTFLDR}/vdrcpu ${OUTPUTFLDR}/vdrmem
# vdr cpu usage, is 10th element in "top" list
top -n 1 | grep " vdr " | awk -F " " '{ print $10;}' > ${OUTPUTFLDR}/vdrcpu
# vdr memory usage, is 11th element in "top" list
top -n 1 | grep " vdr " | awk -F " " '{ print $11;}' > ${OUTPUTFLDR}/vdrmem
read vdr_cpu vdr_mem < <(ps -C vdr -o %cpu=,%mem= | sort | tail -n1)
echo $vdr_cpu > ${OUTPUTFLDR}/vdrcpu
echo $vdr_mem > ${OUTPUTFLDR}/vdrmem

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2004-2007 Christian Wieninger
/* -*- c++ -*-
Copyright (C) 2004-2013 Christian Wieninger
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -24,10 +24,6 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#ifndef EPGSEARCHSERVICES_INC
#define EPGSEARCHSERVICES_INC
// Added by Andreas Mair (mail _AT_ andreas _DOT_ vdr-developer _DOT_ org)
#define EPGSEARCH_SEARCHRESULTS_SERVICE_STRING_ID "Epgsearch-searchresults-v1.0"
#define EPGSEARCH_LASTCONFLICTINFO_SERVICE_STRING_ID "Epgsearch-lastconflictinfo-v1.0"
#include <string>
#include <list>
#include <memory>
@ -35,133 +31,172 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#include <vdr/osdbase.h>
// Data structure for service "Epgsearch-search-v1.0"
struct Epgsearch_search_v1_0
{
struct Epgsearch_search_v1_0 {
// in
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
// out
cOsdMenu* pResultMenu; // pointer to the menu of results
cOsdMenu* pResultMenu; // pointer to the menu of results
};
// Data structure for service "Epgsearch-exttimeredit-v1.0"
struct Epgsearch_exttimeredit_v1_0
{
struct Epgsearch_exttimeredit_v1_0 {
// in
cTimer* timer; // pointer to the timer to edit
bool bNew; // flag that indicates, if this is a new timer or an existing one
const cEvent* event; // pointer to the event corresponding to this timer (may be NULL)
cTimer* timer; // pointer to the timer to edit
bool bNew; // flag that indicates, if this is a new timer or an existing one
const cEvent* event; // pointer to the event corresponding to this timer (may be NULL)
// out
cOsdMenu* pTimerMenu; // pointer to the menu of results
cOsdMenu* pTimerMenu; // pointer to the menu of results
};
// Data structure for service "Epgsearch-enablesearchtimers-v1.0"
struct Epgsearch_enablesearchtimers_v1_0 {
// in
bool enable; // enable search timer thread?
};
// Data structure for service "Epgsearch-updatesearchtimers-v1.0"
struct Epgsearch_updatesearchtimers_v1_0
{
struct Epgsearch_updatesearchtimers_v1_0 {
// in
bool showMessage; // inform via osd when finished?
bool showMessage; // inform via osd when finished?
};
// Data structure for service "Epgsearch-osdmessage-v1.0"
struct Epgsearch_osdmessage_v1_0
{
struct Epgsearch_osdmessage_v1_0 {
// in
char* message; // the message to display
eMessageType type;
char* message; // the message to display
eMessageType type;
};
// Data structure for service "EpgsearchMenu-v1.0"
struct EpgSearchMenu_v1_0
{
struct EpgSearchMenu_v1_0 {
// in
// out
cOsdMenu* Menu; // pointer to the menu
cOsdMenu* Menu; // pointer to the menu
};
// Data structure for service "Epgsearch-lastconflictinfo-v1.0"
struct Epgsearch_lastconflictinfo_v1_0
{
struct Epgsearch_lastconflictinfo_v1_0 {
// in
// out
time_t nextConflict; // next conflict date, 0 if none
int relevantConflicts; // number of relevant conflicts
int totalConflicts; // total number of conflicts
time_t nextConflict; // next conflict date, 0 if none
int relevantConflicts; // number of relevant conflicts
int totalConflicts; // total number of conflicts
};
// Data structure for service "Epgsearch-searchresults-v1.0"
struct Epgsearch_searchresults_v1_0
{
struct Epgsearch_searchresults_v1_0 {
// in
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
// out
class cServiceSearchResult : public cListObject
{
public:
const cEvent* event;
cServiceSearchResult(const cEvent* Event) : event(Event) {}
};
class cServiceSearchResult : public cListObject
{
public:
const cEvent* event;
cServiceSearchResult(const cEvent* Event) : event(Event) {}
};
cList<cServiceSearchResult>* pResultList; // pointer to the results
cList<cServiceSearchResult>* pResultList; // pointer to the results
};
// Data structure for service "Epgsearch-switchtimer-v1.0"
struct Epgsearch_switchtimer_v1_0
{
struct Epgsearch_switchtimer_v1_0 {
// in
const cEvent* event;
int mode; // mode (0=query existance, 1=add/modify, 2=delete)
const cEvent* event;
int mode; // mode (0=query existence, 1=add/modify, 2=delete)
// in/out
int switchMinsBefore;
int announceOnly;
// out
bool success; // result
int switchMinsBefore;
int announceOnly;
// out
bool success; // result
};
// Data structures for service "Epgsearch-services-v1.0"
class cServiceHandler
{
public:
virtual std::list<std::string> SearchTimerList() = 0;
// returns a list of search timer entries in the same format as used in epgsearch.conf
virtual int AddSearchTimer(const std::string&) = 0;
// adds a new search timer and returns its ID (-1 on error)
virtual bool ModSearchTimer(const std::string&) = 0;
// edits an existing search timer and returns success
virtual bool DelSearchTimer(int) = 0;
// deletes search timer with given ID and returns success
virtual std::list<std::string> QuerySearchTimer(int) = 0;
// returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> QuerySearch(std::string) = 0;
// returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> ExtEPGInfoList() = 0;
// returns a list of extended EPG categories in the same format as used in epgsearchcats.conf
virtual std::list<std::string> ChanGrpList() = 0;
// returns a list of channel groups maintained by epgsearch
virtual std::list<std::string> BlackList() = 0;
// returns a list of blacklists in the same format as used in epgsearchblacklists.conf
virtual std::set<std::string> DirectoryList() = 0;
// List of all recording directories used in recordings, timers, search timers or in epgsearchdirs.conf
virtual ~cServiceHandler() {}
// Read a setup value
virtual std::string ReadSetupValue(const std::string& entry) = 0;
// Write a setup value
virtual bool WriteSetupValue(const std::string& entry, const std::string& value) = 0;
public:
virtual std::list<std::string> SearchTimerList() = 0;
// returns a list of search timer entries in the same format as used in epgsearch.conf
virtual int AddSearchTimer(const std::string&) = 0;
// adds a new search timer and returns its ID (-1 on error)
virtual bool ModSearchTimer(const std::string&) = 0;
// edits an existing search timer and returns success
virtual bool DelSearchTimer(int) = 0;
// deletes search timer with given ID and returns success
virtual std::list<std::string> QuerySearchTimer(int) = 0;
// returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> QuerySearch(std::string) = 0;
// returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> ExtEPGInfoList() = 0;
// returns a list of extended EPG categories in the same format as used in epgsearchcats.conf
virtual std::list<std::string> ChanGrpList() = 0;
// returns a list of channel groups maintained by epgsearch
virtual std::list<std::string> BlackList() = 0;
// returns a list of blacklists in the same format as used in epgsearchblacklists.conf
virtual std::set<std::string> DirectoryList() = 0;
// List of all recording directories used in recordings, timers, search timers or in epgsearchdirs.conf
virtual ~cServiceHandler() {}
// Read a setup value
virtual std::string ReadSetupValue(const std::string& entry) = 0;
// Write a setup value
virtual bool WriteSetupValue(const std::string& entry, const std::string& value) = 0;
};
struct Epgsearch_services_v1_0
{
struct Epgsearch_services_v1_0 {
// in/out
std::unique_ptr<cServiceHandler> handler;
#if __cplusplus < 201103L
std::auto_ptr<cServiceHandler> handler;
#else
std::unique_ptr<cServiceHandler> handler;
#endif
};
// Data structures for service "Epgsearch-services-v1.1"
class cServiceHandler_v1_1 : public cServiceHandler
{
public:
// Get timer conflicts
virtual std::list<std::string> TimerConflictList(bool relOnly = false) = 0;
// Check if a conflict check is advised
virtual bool IsConflictCheckAdvised() = 0;
};
struct Epgsearch_services_v1_1 {
// in/out
#if __cplusplus < 201103L
std::auto_ptr<cServiceHandler_v1_1> handler;
#else
std::unique_ptr<cServiceHandler_v1_1> handler;
#endif
};
// Data structures for service "Epgsearch-services-v1.2"
class cServiceHandler_v1_2 : public cServiceHandler_v1_1
{
public:
// List of all recording directories used in recordings, timers (and optionally search timers or in epgsearchdirs.conf)
virtual std::set<std::string> ShortDirectoryList() = 0;
// Evaluate an expression against an event
virtual std::string Evaluate(const std::string& expr, const cEvent* event) = 0;
};
struct Epgsearch_services_v1_2 {
// in/out
#if __cplusplus < 201103L
std::auto_ptr<cServiceHandler_v1_2> handler;
#else
std::unique_ptr<cServiceHandler_v1_2> handler;
#endif
};
#endif

131
services/epgtimer.h Normal file
View File

@ -0,0 +1,131 @@
/*
* service.h: EPG2VDR plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef _SERVICE_H_
#define _SERVICE_H_
#include <vdr/timers.h>
#include <vdr/epg.h>
#include <list>
//***************************************************************************
// Timer - Skin Interface
//***************************************************************************
class cEpgTimer_Interface_V1 : public cTimer
{
public:
enum TimerType
{
ttRecord = 'R', // Aufnahme-Timer
ttView = 'V', // Umschalt-Timer
ttSearch = 'S' // Such-Timer
};
cEpgTimer_Interface_V1(bool Instant = false, bool Pause = false, const cChannel* Channel = 0)
#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
: cTimer(Instant, Pause, Channel) {}
#else
: cTimer(Instant, Pause, (cChannel*)Channel) {}
#endif
long TimerId() const { return timerid; }
long EventId() const { return eventid; }
const char* VdrName() const { return vdrName ? vdrName : ""; }
const char* VdrUuid() const { return vdrUuid ? vdrUuid : ""; }
int isVdrRunning() const { return vdrRunning; }
int isLocal() const { return local; }
int isRemote() const { return !isLocal(); }
int isRecordTimer() const { return type == ttRecord; }
int isSwithTimer() const { return type == ttView; }
char State() const { return state; }
int hasState(char s) const { return state == s; }
const char* StateInfo() const { return stateInfo ? stateInfo : ""; }
char Action() const { return action; }
char Type() const { return type; }
time_t CreateTime() const { return createTime; }
time_t ModTime() const { return modTime; }
protected:
long timerid;
long eventid;
char* vdrName;
char* vdrUuid;
int local;
int vdrRunning;
char state;
char* stateInfo;
char action;
char type;
time_t createTime;
time_t modTime;
};
//***************************************************************************
// Timer Service
//***************************************************************************
struct cEpgTimer_Service_V1
{
std::list<cEpgTimer_Interface_V1*> epgTimers;
};
//***************************************************************************
// Timer Detail Service
//***************************************************************************
struct cTimer_Detail_V1
{
long eventid;
int hastimer;
int local;
char type;
};
#define EPG2VDR_TIMER_DETAIL_SERVICE "Epg2Vdr_Timer_Detail_Service-v1.0"
#define EPG2VDR_TIMER_SERVICE "Epg2Vdr_Timer_Service-v1.0"
#ifdef EPG2VDR
//***************************************************************************
//***************************************************************************
//***************************************************************************
// EPG2VDR Internal Stuff
//***************************************************************************
//***************************************************************************
// Class cEpgTimer
//***************************************************************************
class cEpgTimer : public cEpgTimer_Interface_V1
{
public:
cEpgTimer(bool Instant = false, bool Pause = false, const cChannel* Channel = 0);
virtual ~cEpgTimer();
void setTimerId(long id) { timerid = id; }
void setEventId(long id) { eventid = id; }
void setAction(char a) { action = a; }
void setType(char t) { type = t; }
void setCreateTime(time_t t) { createTime = t; }
void setModTime(time_t t) { modTime = t; }
void setState(char s, const char* info);
void setVdr(const char* name, const char* uuid = 0, int running = 0);
};
#endif // EPG2VDR
//***************************************************************************
#endif // _SERVICE_H_

29
setup.c
View File

@ -119,6 +119,8 @@ eOSState cInstallManager::ProcessInstallationStatus(void) {
}
// --- cSkinDesignerSetup -----------------------------------------------------------
bool cSkinDesignerSetup::skinrepoUpdated = false;
cSkinDesignerSetup::cSkinDesignerSetup(skindesignerapi::cPluginStructure *skinPreviewStruct) {
this->skinPreviewStruct = skinPreviewStruct;
numLogosPerSizeInitial = config.numLogosPerSizeInitial;
@ -126,12 +128,21 @@ cSkinDesignerSetup::cSkinDesignerSetup(skindesignerapi::cPluginStructure *skinPr
limitLogoCache = config.limitLogoCache;
numLogosMax = config.numLogosMax;
debugImageLoading = config.debugImageLoading;
useSubtitleRerun = config.useSubtitleRerun;
rerunAmount = config.rerunAmount;
rerunDistance = config.rerunDistance;
rerunMaxChannel = config.rerunMaxChannel;
numCustomTokens = config.numCustomTokens;
FPS = config.FPS;
menuDisplayStyle[0] = tr("after one another");
menuDisplayStyle[1] = tr("at one go");
#ifndef DO_NOT_USE_SKININSTALLER
if (!skinrepoUpdated) {
Skins.Message(mtStatus, *cString::sprintf("%s...", tr("Updating Skinrepositories")));
skinrepoUpdated = true;
config.ReadSkinRepos();
}
#endif
Setup();
}
@ -231,7 +242,7 @@ eOSState cSkinDesignerSetup::ProcessKey(eKeys Key) {
}
Skins.Message(mtStatus, *cString::sprintf("%s ...", tr("Updating Skin from Git")));
} else {
Skins.Message(mtStatus, tr("No Git Repsoitory available"));
Skins.Message(mtStatus, tr("No Git Repository available"));
}
}
}
@ -259,10 +270,12 @@ void cSkinDesignerSetup::Store(void) {
config.limitLogoCache = limitLogoCache;
config.numLogosMax = numLogosMax;
config.debugImageLoading = debugImageLoading;
config.useSubtitleRerun = useSubtitleRerun;
config.rerunAmount = rerunAmount;
config.rerunDistance = rerunDistance;
config.rerunMaxChannel = rerunMaxChannel;
config.numCustomTokens = numCustomTokens;
config.FPS = FPS;
config.InitSetupIterator();
cSkinSetup *skinSetup = NULL;
@ -283,10 +296,12 @@ void cSkinDesignerSetup::Store(void) {
SetupStore("LimitChannelLogoCache", limitLogoCache);
SetupStore("NumberLogosInitially", numLogosPerSizeInitial);
SetupStore("NumberLogosMax", numLogosMax);
SetupStore("UseSubtitleRerun", useSubtitleRerun);
SetupStore("RerunAmount", rerunAmount);
SetupStore("RerunDistance", rerunDistance);
SetupStore("RerunMaxChannel", rerunMaxChannel);
SetupStore("NumCustomTokens", numCustomTokens);
SetupStore("FPS", FPS);
}
cOsdItem *cSkinDesignerSetup::InfoItem(const char *label) {
@ -299,9 +314,11 @@ cOsdItem *cSkinDesignerSetup::InfoItem(const char *label) {
void cSkinDesignerSetup::PluginSetup(void) {
Add(InfoItem(tr("Plugin Setup")));
Add(new cMenuEditIntItem(tr("Frames per Second to display animations"), &FPS, 10, 60));
Add(new cMenuEditIntItem(tr("Maximum number of custom tokens"), &numCustomTokens, 0, 100));
Add(InfoItem(tr("Reruns")));
Add(new cMenuEditBoolItem(tr("Use Subtitle for reruns"), &useSubtitleRerun));
Add(new cMenuEditIntItem(tr("Maximum number of reruns to display"), &rerunAmount, 1, 100));
Add(new cMenuEditIntItem(tr("Minimum timely distance of rerun (in hours)"), &rerunDistance, 0, 1000));
Add(new cMenuEditIntItem(tr("Limit Channel Numbers"), &rerunMaxChannel, 0, 1000, tr("no limit")));
@ -360,7 +377,7 @@ void cSkinDesignerSetup::SkinSetup(void) {
}
void cSkinDesignerSetup::InstallSkins(void) {
#ifdef USE_SKININSTALLER
#ifndef DO_NOT_USE_SKININSTALLER
Add(InfoItem(tr("Install new skins")));
config.InitSkinRepoIterator();
@ -441,7 +458,7 @@ eOSState cSkindesignerSkinSetup::ProcessKey(eKeys Key) {
}
Skins.Message(mtStatus, *cString::sprintf("%s ...", tr("Updating Skin from Git")));
} else {
Skins.Message(mtStatus, tr("No Git Repsoitory available"));
Skins.Message(mtStatus, tr("No Git Repository available"));
}
break;
}
@ -497,6 +514,10 @@ void cSkindesignerSkinSetup::Set(void) {
Add(new cMenuEditBoolItem(param->displayText.c_str(), &param->value));
} else if (param->type == sptString) {
Add(new cMenuEditStraItem(param->displayText.c_str(), &param->value, param->numOptions, param->optionsTranslated));
} else if (param->type == sptSeparator) {
cOsdItem *item = new cOsdItem(param->displayText.c_str());
item->SetSelectable(false);
Add(item);
}
helpTexts.push_back(param->helpText);
}
@ -524,7 +545,7 @@ void cSkindesignerSkinSetup::ShowButtons(int current, bool force) {
// --- cSkindesignerSkinPreview -----------------------------------------------------------
cSkindesignerSkinPreview::cSkindesignerSkinPreview(string skin, skindesignerapi::cPluginStructure *plugStruct) :
cSkindesignerOsdMenu(plugStruct, *cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), skin.c_str())) {
cSkindesignerOsdMenu(plugStruct, *cString::sprintf("%s: %s \"%s\"", tr("Preview"), tr("Skin"), skin.c_str())) {
currentSkin = skin;
FirstCallCleared();
Set();

View File

@ -38,16 +38,19 @@ public:
// --- cSkinDesignerSetup -----------------------------------------------------------
class cSkinDesignerSetup : public cMenuSetupPage, cInstallManager {
private:
static bool skinrepoUpdated;
skindesignerapi::cPluginStructure *skinPreviewStruct;
int numLogosPerSizeInitial;
int cacheImagesInitial;
int limitLogoCache;
int numLogosMax;
int debugImageLoading;
int useSubtitleRerun;
int rerunAmount;
int rerunDistance;
int rerunMaxChannel;
int numCustomTokens;
int FPS;
const char *menuDisplayStyle[2];
void Setup(void);
virtual void Store(void);
@ -122,4 +125,4 @@ public:
static void DefineTokens(skindesignerapi::cTokenContainer *tk);
void Display(void);
};
#endif //__SKINDESIGNER_SETUP_H
#endif //__SKINDESIGNER_SETUP_H

View File

@ -7,19 +7,20 @@
*/
#include <getopt.h>
#include <vdr/plugin.h>
#include <vdr/device.h>
#define DEFINE_CONFIG 1
#include "config.h"
#include "designer.h"
#include "setup.h"
#include "libskindesignerapi/skindesignerapi.h"
#include "extensions/globaltimers.h"
#if defined(APIVERSNUM) && APIVERSNUM < 20200
#error "VDR-2.2.0 API version or greater is required!"
#endif
static const char *VERSION = "0.9.5";
static const char *VERSION = "1.2.18";
static const char *DESCRIPTION = trNOOP("Skin Designer");
class cPluginSkinDesigner : public cPlugin, public skindesignerapi::SkindesignerAPI {
@ -111,8 +112,9 @@ bool cPluginSkinDesigner::Initialize(void) {
bool cPluginSkinDesigner::Start(void) {
cXmlParser::InitLibXML();
cImageImporterSVG::InitLibRSVG();
cGlobalTimers::StartRefreshThread();
bool trueColorAvailable = true;
if (!cOsdProvider::SupportsTrueColor()) {
esyslog("skindesigner: No TrueColor OSD found! Using default Skin LCARS!");
trueColorAvailable = false;
@ -151,11 +153,13 @@ bool cPluginSkinDesigner::Start(void) {
}
config.TranslateSetup();
config.SetSkinSetupParameters();
config.ReadSkinRepos();
if (!skinAvailable) {
esyslog("skindesigner: no skins found! Using default Skin LCARS!");
}
#ifdef USE_ZAPCOCKPIT
dsyslog("skindesigner: zapcockpit patch available");
#endif
return true;
}
@ -164,12 +168,28 @@ void cPluginSkinDesigner::Stop(void) {
delete fontManager;
delete plgManager;
cXmlParser::CleanupLibXML();
cGlobalTimers::StopRefreshThread();
}
void cPluginSkinDesigner::Housekeeping(void) {
}
void cPluginSkinDesigner::MainThreadHook(void) {
int w, h;
double a;
static int mode;
cDevice::PrimaryDevice()->GetVideoSize(w, h, a);
if (!w && !h && !mode) {
mode = 1;
config.mode_changed = 1;
dsyslog("skindesigner: w %d h %d mode changed to %d\n", w, h, mode);
}
else if (w && h && mode) {
mode = 0;
config.mode_changed = 1;
dsyslog("skindesigner: w %d h %d mode changed to %d\n", w, h, mode);
}
}
cString cPluginSkinDesigner::Active(void) {
@ -216,10 +236,11 @@ const char **cPluginSkinDesigner::SVDRPHelpPages(void) {
}
cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) {
cSkinDesigner *activeSkin = NULL;
cSkinDesigner *availableSkin = NULL;
config.InitSkinRefsIterator();
int result = 0;
while (availableSkin = config.GetNextSkinRef()) {
string activeSkinName = Setup.OSDSkin;
string currentSkinName = availableSkin->Description();
@ -235,6 +256,10 @@ cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Optio
}
if (strcasecmp(Command, "RELD") == 0) {
if (!activeSkin->Initialized()) {
ReplyCode = 503;
return "SKINDESIGNER reload of templates and caches failed: initialization not finished.";
}
config.ClearSkinSetups();
config.InitSkinIterator();
string skin = "";
@ -243,9 +268,21 @@ cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Optio
}
config.TranslateSetup();
config.SetSkinSetupParameters();
activeSkin->Reload();
ReplyCode = 250;
return "SKINDESIGNER reload of templates and caches forced.";
result = activeSkin->Reload();
switch (result) {
case 0:
ReplyCode = 250;
return "SKINDESIGNER reload of templates and caches forced.";
case 1:
ReplyCode = 501;
return "SKINDESIGNER reload of templates and caches failed: error during loading - using LCARS as backup.";
case 2:
ReplyCode = 503;
return "SKINDESIGNER reload of templates and caches failed: OSD is open, close first.";
default:
ReplyCode = 500;
return "SKINDESIGNER reload of templates and caches failed: unknown reason (check code).";
};
} else if (strcasecmp(Command, "DLIC") == 0) {
if (imgCache)
delete imgCache;

Binary file not shown.

View File

@ -0,0 +1,40 @@
DS-Font's TrueType Fonts
Font name: DS-Digital (Normal, Bold, Italic, Bold Italic), Version 1.0
Author: Dusit Supasawat
Web Site: http://ds-font.hypermart.net
Contact me: Dusit Supasawat, 325/38 Suksawat32 Ratburana Bangkok Thailand 10140
Email address: dusit@mailcity.com
Thanks for trying! We hope you really enjoy this my typeface. This font is
distributed as shareware. You can use this font for a long time as you want.
After all, when you think this font can be usefulness for you. You can send
me some money, that would be way cool.
I'm only asking $20 US shareware fee per this typeface for personal use.
And $45 US is the usual amount per this typeface for commercial use.
Distribution: You are free to distribute this archive so long as this text
file is distributed with the archive, the font file have not been modified,
and it is understood that the font's copyright remains with the original
author (Dusit Supasawat).
To register send your payment to:
Dusit Supasawat
325/38 Suksawat32 Ratburana
Bangkok Thailand 10140
And fill out something as this order form, and send it in with your payment.
Font name:_________________________________________
Your information
Name:______________________________________________
Address:___________________________________________
City, State : _____________________________________
Zip Code:__________________________________________
Country:___________________________________________
E-MAIL address:____________________________________
You will receive fonts which you order by Email after registration. These fonts
will be generated for you by specify your name in font information.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,48 @@
Copyright (c) 2010-2014, Łukasz Dziedzic (dziedzic@typoland.com),
with Reserved Font Name Lato.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More