openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #02928
[Merge] lp:~j-corwin/openlp/render into lp:~trb143/openlp/renderer
Jonathan Corwin has proposed merging lp:~j-corwin/openlp/render into lp:~trb143/openlp/renderer.
Requested reviews:
OpenLP Core (openlp-core)
Alerts over presentations and other fixes.
NOTE This is a merge request for Tims branch, not trunk.
--
https://code.launchpad.net/~j-corwin/openlp/render/+merge/33246
Your team OpenLP Core is requested to review the proposed merge of lp:~j-corwin/openlp/render into lp:~trb143/openlp/renderer.
=== modified file 'openlp/core/lib/htmlbuilder.py'
--- openlp/core/lib/htmlbuilder.py 2010-08-07 06:18:05 +0000
+++ openlp/core/lib/htmlbuilder.py 2010-08-20 18:26:42 +0000
@@ -33,33 +33,60 @@
<style>
*{
margin: 0;
- padding:0
+ padding: 0;
+ border: 0;
}
body {
background-color: black;
}
-%s
-%s
-%s
-%s
-%s
-%s
-%s
+.dim {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: %spx;
+ height: %spx;
+}
+#black {
+ z-index:8;
+ background-color: black;
+ display: none;
+}
+#video {
+ z-index:2;
+}
+#alert {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ z-index:10;
+ %s
+}
+#footer {
+ position: absolute;
+ z-index:5;
+ %s
+}
+/* lyric css */
+%s
+
</style>
<script language="javascript">
- var t = null;
+ var timer = null;
var transition = %s;
- function video(state, path, volume, loop){
+ function show_video(state, path, volume, loop){
var vid = document.getElementById('video');
- if(path!=null)
+ if(path != null)
vid.src = path;
- if(loop!=null){
+ if(loop != null){
if(loop)
vid.loop = 'loop';
else
vid.loop = '';
}
+ if(volume != null){
+ vid.volume = volume;
+ }
switch(state){
case 'play':
vid.play();
@@ -76,22 +103,20 @@
case 'close':
vid.pause();
vid.style.display = 'none';
- vid.setAttribute('src', '');
+ vid.src = '';
break;
- if(volume!=null)
- vid.volume = volume;
}
}
- function setImage(src){
+ function show_image(src){
var img = document.getElementById('image');
img.src = src;
- if(src=='')
+ if(src == '')
img.style.display = 'none';
else
img.style.display = 'block';
}
- function blankState(state){
+ function show_blank(state){
var black = 'none';
var lyrics = '';
var pause = false;
@@ -122,36 +147,39 @@
}
}
- function displayAlert(alerttext, shrink){
+ function show_alert(alerttext, position){
var text = document.getElementById('alert');
text.innerHTML = alerttext;
- if(alerttext=='') {
+ if(alerttext == '') {
text.style.visibility = 'hidden';
return 0;
}
- if(shrink){
- text.style.top = '0px';
+ if(position == ''){
+ position = window.getComputedStyle(text, '').verticalAlign;
}
- else
+ switch(position)
{
- switch(window.getComputedStyle(text, '').verticalAlign)
- {
- case 'top':
- text.style.top = '0px';
- break;
- case 'middle':
- text.style.top = ((window.innerHeight - text.clientHeight) / 2) + 'px';
- break;
- case 'bottom':
- text.style.top = (window.innerHeight - text.clientHeight) + 'px';
- break;
- }
+ case 'top':
+ text.style.top = '0px';
+ break;
+ case 'middle':
+ text.style.top = ((window.innerHeight - text.clientHeight) / 2)
+ + 'px';
+ break;
+ case 'bottom':
+ text.style.top = (window.innerHeight - text.clientHeight)
+ + 'px';
+ break;
}
text.style.visibility = 'visible';
return text.clientHeight;
}
- function startfade(newtext){
+ function show_footer(text){
+ document.getElementById('footer').innerHTML(text);
+ }
+
+ function show_text(newtext){
var text1 = document.getElementById('lyricsmain');
var texto1 = document.getElementById('lyricsoutline');
var texts1 = document.getElementById('lyricsshadow');
@@ -164,7 +192,8 @@
var text2 = document.getElementById('lyricsmain2');
var texto2 = document.getElementById('lyricsoutline2');
var texts2 = document.getElementById('lyricsshadow2');
- if(text2.style.opacity==''||parseFloat(text2.style.opacity) < 0.5){
+ if((text2.style.opacity == '')||(parseFloat(text2.style.opacity) < 0.5))
+ {
text2.innerHTML = text1.innerHTML;
text2.style.opacity = text1.style.opacity;
texto2.innerHTML = text1.innerHTML;
@@ -178,15 +207,14 @@
texto1.innerHTML = newtext;
texts1.style.opacity = 0;
texts1.innerHTML = newtext;
- // temp:
+ // For performance reasons, we'll not animate the shadow for now
texts2.style.opacity = 0;
- // end temp
- if(t!=null)
- clearTimeout(t);
- t = setTimeout('fade()', 50);
+ if(timer != null)
+ clearTimeout(timer);
+ timer = setTimeout('text_fade()', 50);
}
- function fade(){
+ function text_fade(){
var text1 = document.getElementById('lyricsmain');
var texto1 = document.getElementById('lyricsoutline');
var texts1 = document.getElementById('lyricsshadow');
@@ -196,16 +224,19 @@
if(parseFloat(text1.style.opacity) < 1){
text1.style.opacity = parseFloat(text1.style.opacity) + 0.1;
texto1.style.opacity = parseFloat(texto1.style.opacity) + 0.1;
+ // Don't animate shadow (performance)
//texts1.style.opacity = parseFloat(texts1.style.opacity) + 0.1;
}
if(parseFloat(text2.style.opacity) > 0){
text2.style.opacity = parseFloat(text2.style.opacity) - 0.1;
texto2.style.opacity = parseFloat(texto2.style.opacity) - 0.1;
+ // Don't animate shadow (performance)
//texts2.style.opacity = parseFloat(texts2.style.opacity) - 0.1;
}
- if((parseFloat(text1.style.opacity) < 1)||(parseFloat(text2.style.opacity) > 0))
- t = setTimeout('fade()', 50);
- else{
+ if((parseFloat(text1.style.opacity) < 1) ||
+ (parseFloat(text2.style.opacity) > 0)){
+ t = setTimeout('text_fade()', 50);
+ } else {
text1.style.opacity = 1;
texto1.style.opacity = 1;
texts1.style.opacity = 1;
@@ -215,12 +246,22 @@
}
}
- function fadeFinished(){
- return (document.getElementById('lyricsmain').style.opacity==1);
+ function show_text_complete(){
+ return (document.getElementById('lyricsmain').style.opacity == 1);
}
</script>
</head>
<body>
+<!--
+Using tables, rather than div's to make use of the vertical-align style that
+doesn't work on div's. This avoids the need to do positioning manually which
+could get messy when changing verses esp. with transitions
+
+Would prefer to use a single table and make use of -webkit-text-fill-color
+-webkit-text-stroke and text-shadow styles, but they have problems working/
+co-operating in qwebkit. https://bugs.webkit.org/show_bug.cgi?id=43187
+Therefore one table for text, one for outline and one for shadow.
+-->
<table class="lyricstable lyricscommon">
<tr><td id="lyricsmain" class="lyrics"></td></tr>
</table>
@@ -239,18 +280,11 @@
<table class="lyricsshadowtable lyricscommon">
<tr><td id="lyricsshadow2" class="lyricsshadow lyrics"></td></tr>
</table>
-<!--
-<table class="alerttable">
- <tr><td class="alertcell">
- <div class="alert" id="alertmain"></div>
- </td></tr>
-</table>
--->
<div id="alert" style="visibility:hidden;"></div>
<div id="footer" class="footer"></div>
-<video id="video"></video>
-<div id="black"></div>
-%s
+<video class="dim" id="video"></video>
+<div class="dim" id="black"></div>
+<img class="dim" id="image" src="%s" />
</body>
</html>
"""
@@ -269,80 +303,18 @@
width = screen[u'size'].width()
height = screen[u'size'].height()
theme = item.themedata
- html = HTMLSRC % (build_video(width, height),
- build_image(width, height),
- build_lyrics(item),
- build_footer(item),
- build_alert(width, height, alert),
- build_image(width, height),
- build_black(width, height),
- "true" if theme and
- theme.display_slideTransition else "false",
- build_image_src(item.bg_frame))
+ if item.bg_frame:
+ image = u'data:image/png;base64,%s' % image_to_byte(item.bg_frame)
+ else:
+ image = u''
+ html = HTMLSRC % (width, height,
+ build_alert(alert, width),
+ build_footer(item),
+ build_lyrics(item),
+ u'true' if theme and theme.display_slideTransition else u'false',
+ image)
return html
-def build_video(width, height):
- """
- Build the video display div
-
- `width`
- Screen width
- `height`
- Screen height
- """
- video = """
- #video { position: absolute; left: 0px; top: 0px;
- width: %spx; height: %spx; z-index:2; }
- """
- return video % (width, height)
-
-def build_black(width, height):
- """
- Build the black display div
-
- `width`
- Screen width
- `height`
- Screen height
- """
- black = """
- #black { position: absolute; left: 0px; top: 0px;
- width: %spx; height: %spx; z-index:8;
- background-color: black; display: none;
- }
- """
- return black % (width, height)
-
-def build_image(width, height):
- """
- Build the image display div
-
- `width`
- Screen width
- `height`
- Screen height
- """
- image = """
- #image { position: absolute; left: 0px; top: 0px;
- width: %spx; height: %spx; z-index:1;
- }
- """
- return image % (width, height)
-
-def build_image_src(image):
- """
- Build display for the backgroung image
-
- `image`
- Image to be displayed
- """
- if image:
- return '<img id="image" src="data:image/png;base64,%s" />' % \
- image_to_byte(image)
- else:
- return '<img id="image" />'
-
-
def build_lyrics(item):
"""
Build the video display div
@@ -358,7 +330,6 @@
.lyrics { %s }
.lyricsoutline { %s }
.lyricsshadow { %s }
- table {border=0; margin=0; padding=0; }
"""
theme = item.themedata
lyricscommon = u''
@@ -408,7 +379,6 @@
shadow = u'color: %s;' % (theme.display_shadow_color)
lyrics_html = style % (lyricscommon, lyricstable, outlinetable,
shadowtable, lyrics, outline, shadow)
- print lyrics_html
return lyrics_html
def build_footer(item):
@@ -418,64 +388,54 @@
`item`
Service Item to be processed.
"""
- lyrics = """
- #footer {position: absolute; %s z-index:5; %s; %s }
+ style = """
+ left: %spx;
+ top: %spx;
+ width: %spx;
+ height: %spx;
+ font-family: %s;
+ font-size: %spx;
+ color: %s;
+ align: %s;
"""
theme = item.themedata
- lyrics_html = u''
- position = u''
- font = u''
- text = u''
- if theme:
- position = u' left: %spx; top: %spx; width: %spx; height: %spx; ' % \
- (item.footer.x(), item.footer.y(), item.footer.width(),
- item.footer.height())
- font = u' font-family %s; font-size: %spx;' % \
- (theme.font_footer_name, theme.font_footer_proportion)
- align = u''
- if theme.display_horizontalAlign == 2:
- align = u'align:center;'
- elif theme.display_horizontalAlign == 1:
- align = u'align:right;'
- text = u'color:%s; %s ' % (theme.font_footer_color, align)
- lyrics_html = lyrics % (position, font, text)
+ if not theme:
+ return u''
+ if theme.display_horizontalAlign == 2:
+ align = u'center'
+ elif theme.display_horizontalAlign == 1:
+ align = u'right'
+ else:
+ align = u'left'
+ lyrics_html = style % (item.footer.x(), item.footer.y(),
+ item.footer.width(), item.footer.height(), theme.font_footer_name,
+ theme.font_footer_proportion, theme.font_footer_color, align)
return lyrics_html
-def build_alert(width, height, alertTab):
+def build_alert(alertTab, width):
"""
Build the display of the footer
- `width`
- Screen Width
- `height`
- Screen height
`alertTab`
Details from the Alert tab for fonts etc
"""
style = """
- .alerttable { position: absolute; z-index:10; left 0px; top 0px; %s }
- .alertcell { %s }
- .alert { %s }
- """
- style2 = """
- #alert {position: absolute; z-index:10; left 0px; top 0px; width: %spx; %s %s}
+ width: %s;
+ vertical-align: %s;
+ font-family %s;
+ font-size: %spx;
+ color: %s;
+ background-color: %s;
"""
- alerttable = u''
- alertcell = u''
- alert = u''
- if alertTab:
- if alertTab.location == 2:
- alertcell = u'vertical-align:bottom;'
- elif alertTab.location == 1:
- alertcell = u'vertical-align:middle;'
- else:
- alertcell = u'vertical-align:top;'
- alerttable = u'width: %spx; height: %spx; ' % (width, height)
- alert = u'font-family %s; font-size: %spx; color: %s; ' \
- u'background-color: %s' % \
- (alertTab.font_face, alertTab.font_size, alertTab.font_color,
- alertTab.bg_color)
- #alert_html = style % (alerttable, alertcell, alert)
- alert_html = style2 % (width, alertcell, alert)
- print alert_html
- return alert_html
+ if not alertTab:
+ return u''
+ align = u''
+ if alertTab.location == 2:
+ align = u'bottom'
+ elif alertTab.location == 1:
+ align = u'middle'
+ else:
+ align = u'top'
+ alert = style % (width, align, alertTab.font_face, alertTab.font_size,
+ alertTab.font_color, alertTab.bg_color)
+ return alert
=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py 2010-08-07 13:37:10 +0000
+++ openlp/core/ui/maindisplay.py 2010-08-20 18:26:42 +0000
@@ -113,7 +113,7 @@
self.page = self.webView.page()
self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView,
- QtCore.SIGNAL(u'loadFinished(bool)'), self.loaded)
+ QtCore.SIGNAL(u'loadFinished(bool)'), self.isLoaded)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
@@ -162,11 +162,11 @@
The slide text to be displayed
"""
log.debug(u'text')
- self.frame.evaluateJavaScript("startfade('" +
- slide.replace("\\", "\\\\").replace("\'", "\\\'") + "')")
+ self.frame.evaluateJavaScript(u'show_text("%s")' % \
+ slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
return self.preview()
- def alert(self, text, shrink=False):
+ def alert(self, text):
"""
Add the alert text
@@ -174,15 +174,22 @@
The slide text to be displayed
"""
log.debug(u'alert')
- js = "displayAlert('" + \
- text.replace("\\", "\\\\").replace("\'", "\\\'") + "', %s)" % \
- ('true' if shrink else 'false')
+ if self.height() != self.screen[u'size'].height() \
+ or not self.isVisible():
+ shrink = True
+ else:
+ shrink = False
+ js = u'show_alert("%s", "%s")' % (
+ text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'),
+ u'top' if shrink else u'')
height = self.frame.evaluateJavaScript(js)
if shrink:
if text:
self.resize(self.width(), int(height.toString()))
+ self.setVisible(True)
else:
self.setGeometry(self.screen[u'size'])
+ self.setVisible(False)
def image(self, image):
"""
@@ -203,10 +210,10 @@
Display an image, as is.
"""
if image:
- js = "setImage('" + \
- u'data:image/png;base64,%s' % image_to_byte(image) + "');"
+ js = u'show_image("data:image/png;base64,%s");' % \
+ image_to_byte(image)
else:
- js = "setImage('');"
+ js = u'show_image("");'
self.frame.evaluateJavaScript(js)
def resetImage(self):
@@ -222,35 +229,35 @@
Used after Video plugin has changed the background
"""
log.debug(u'resetVideo')
- self.frame.evaluateJavaScript('video("close");')
+ self.frame.evaluateJavaScript(u'show_video("close");')
def videoPlay(self):
"""
Responds to the request to play a loaded video
"""
log.debug(u'videoPlay')
- self.frame.evaluateJavaScript('video("play");')
+ self.frame.evaluateJavaScript(u'show_video("play");')
def videoPause(self):
"""
Responds to the request to pause a loaded video
"""
log.debug(u'videoPause')
- self.frame.evaluateJavaScript('video("pause");')
+ self.frame.evaluateJavaScript(u'show_video("pause");')
def videoStop(self):
"""
Responds to the request to stop a loaded video
"""
log.debug(u'videoStop')
- self.frame.evaluateJavaScript('video("stop");')
+ self.frame.evaluateJavaScript(u'show_video("stop");')
def videoVolume(self, volume):
"""
Changes the volume of a running video
"""
log.debug(u'videoVolume %d' % volume)
- self.frame.evaluateJavaScript('video(null,null,%s);' %
+ self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
str(float(volume)/float(10)))
def video(self, videoPath, volume):
@@ -259,13 +266,12 @@
"""
log.debug(u'video')
self.loaded = True
- js = 'video("play","%s",%s,true);' % \
- (videoPath.replace("\\", "\\\\"), str(float(volume)/float(10)))
+ js = u'show_video("play", "%s", %s, true);' % \
+ (videoPath.replace(u'\\', u'\\\\'), str(float(volume)/float(10)))
self.frame.evaluateJavaScript(js)
- print js
return self.preview()
- def loaded(self):
+ def isLoaded(self):
"""
Called by webView event to show display is fully loaded
"""
@@ -280,7 +286,7 @@
# Wait for the fade to finish before geting the preview.
# Important otherwise preview will have incorrect text if at all !
if self.serviceItem.themedata.display_slideTransition:
- while self.frame.evaluateJavaScript("fadeFinished()").toString() == u'false':
+ while self.frame.evaluateJavaScript(u'show_text_complete()').toString() == u'false':
Receiver.send_message(u'openlp_process_events')
# Wait for the webview to update before geting the preview.
# Important otherwise first preview will miss the background !
@@ -295,7 +301,7 @@
painter.end()
# save preview for debugging
if log.isEnabledFor(logging.DEBUG):
- preview.save("temp.png", "png")
+ preview.save(u'temp.png', u'png')
return preview
def buildHtml(self, serviceItem):
@@ -310,7 +316,13 @@
html = build_html(self.serviceItem, self.screen, self.parent.alertTab)
self.webView.setHtml(html)
if serviceItem.footer and serviceItem.foot_text:
- self.frame.findFirstElement('div#footer').setInnerXml(serviceItem.foot_text)
+ self.footer(serviceItem.foot_text)
+
+ def footer(self, text):
+ log.debug(u'footer')
+ js = "show_footer('" + \
+ text.replace("\\", "\\\\").replace("\'", "\\\'") + "')"
+ self.frame.evaluateJavaScript(js)
def hideDisplay(self, mode=HideMode.Screen):
"""
@@ -318,15 +330,13 @@
Store the images so they can be replaced when required
"""
log.debug(u'hideDisplay mode = %d', mode)
- self.frame.evaluateJavaScript(
- "document.getElementById('blank').style.visibility = 'visible'")
if mode == HideMode.Screen:
- self.frame.evaluateJavaScript('blankState("desktop");')
+ self.frame.evaluateJavaScript(u'show_blank("desktop");')
self.setVisible(False)
elif mode == HideMode.Blank or self.initialFrame:
- self.frame.evaluateJavaScript('blankState("black");')
+ self.frame.evaluateJavaScript(u'show_blank("black");')
else:
- self.frame.evaluateJavaScript('blankState("theme");')
+ self.frame.evaluateJavaScript(u'show_blank("theme");')
if mode != HideMode.Screen and self.isHidden():
self.setVisible(True)
@@ -337,7 +347,7 @@
Make the stored images None to release memory.
"""
log.debug(u'showDisplay')
- self.frame.evaluateJavaScript('blankState("show");')
+ self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden():
self.setVisible(True)
# Trigger actions when display is active again