← Back to team overview

openlp-core team mailing list archive

[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