From 305610ed8eb5a42f95754664c0ddcd69112056d1 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Mon, 30 Aug 2010 21:57:59 +0100 Subject: [PATCH 1/6] fixes --- openlp/core/lib/htmlbuilder.py | 54 +++++++++++++++------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 07b9f46ad..0c4a6821c 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -58,20 +58,18 @@ body { position: absolute; left: 0px; top: 0px; - z-index:10; - %s + z-index:10;%s } #footer { position: absolute; - z-index:5; - %s + z-index:5;%s } /* lyric css */ %s - @@ -221,22 +229,13 @@ 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. --> - +
- +
- -
- - -
- - -
- - +
@@ -268,11 +267,13 @@ def build_html(item, screen, alert, islive): html = HTMLSRC % (width, height, build_alert(alert, width), build_footer(item), - build_lyrics(item, islive), + build_lyrics(item), + u'true' if theme and theme.display_slideTransition and islive \ + else u'false', image) return html -def build_lyrics(item, islive): +def build_lyrics(item): """ Build the video display div @@ -280,15 +281,13 @@ def build_lyrics(item, islive): Service Item containing theme and location information """ style = """ -.lyricscommon { position: absolute; %s } -.lyricstable { z-index:4; %s } -.lyricsoutlinetable { z-index:3; %s } -.lyricsshadowtable { z-index:2; %s } -.lyrics { %s } -.lyricsoutline { %s } -.lyricsshadow { %s } -td { opacity: 1; %s } -td.fadeout { opacity: 0; } + .lyricscommon { position: absolute; %s } + .lyricstable { z-index:4; %s } + .lyricsoutlinetable { z-index:3; %s } + .lyricsshadowtable { z-index:2; %s } + .lyrics { %s } + .lyricsoutline { %s } + .lyricsshadow { %s } """ theme = item.themedata lyricscommon = u'' @@ -298,7 +297,6 @@ td.fadeout { opacity: 0; } lyrics = u'' outline = u'display: none;' shadow = u'display: none;' - transition = u'' if theme: lyricscommon = u'width: %spx; height: %spx; word-wrap: break-word; ' \ u'font-family: %s; font-size: %spt; color: %s; line-height: %d%%;' \ @@ -313,8 +311,6 @@ td.fadeout { opacity: 0; } (item.main.x() + float(theme.display_shadow_size), item.main.y() + float(theme.display_shadow_size)) align = u'' - if theme.display_slideTransition and islive: - transition = u'-webkit-transition: opacity 1s linear;' if theme.display_horizontalAlign == 2: align = u'text-align:center;' elif theme.display_horizontalAlign == 1: @@ -342,7 +338,7 @@ td.fadeout { opacity: 0; } if theme.display_shadow: shadow = u'color: %s;' % (theme.display_shadow_color) lyrics_html = style % (lyricscommon, lyricstable, outlinetable, - shadowtable, lyrics, outline, shadow, transition) + shadowtable, lyrics, outline, shadow) return lyrics_html def build_footer(item): From a9281e4cb9447f71d208a5840ae186bd424cea76 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Wed, 1 Sep 2010 22:36:02 +0100 Subject: [PATCH 3/6] replace evil-tables(tm) with div's --- openlp/core/lib/htmlbuilder.py | 44 ++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index db5b84efb..c5b5088c4 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -195,22 +195,23 @@ body { function text_fade(id, newtext){ var text = document.getElementById(id); if(!transition){ - text.innerHTML = newtext; - return; + text.innerHTML = newtext; + return; } if(text.style.opacity=='') text.style.opacity = 1; if(newtext==text.innerHTML){ text.style.opacity = parseFloat(text.style.opacity) + 0.3; } else { text.style.opacity -= 0.3; - if(text.style.opacity<=0.1) + if(text.style.opacity<=0.1){ text.innerHTML = newtext; + } } } function text_opacity(){ var text = document.getElementById('lyricsmain'); - return window.getComputedStyle(text, '').opacity; + return getComputedStyle(text, '').opacity; } function show_text_complete(){ return (text_opacity()==1); @@ -219,24 +220,25 @@ body { - - -
- - -
- - -
+
+
+
+
+
+
+
+
+
@@ -298,7 +300,7 @@ def build_lyrics(item): outline = u'display: none;' shadow = u'display: none;' if theme: - lyricscommon = u'width: %spx; height: %spx; word-wrap: break-word; ' \ + lyricscommon = u'display: table; width: %spx; height: %spx; word-wrap: break-word; ' \ u'font-family: %s; font-size: %spt; color: %s; line-height: %d%%;' \ % (item.main.width(), item.main.height(), theme.font_main_name, theme.font_main_proportion, theme.font_main_color, @@ -323,7 +325,7 @@ def build_lyrics(item): valign = u'vertical-align:middle;' else: valign = u'vertical-align:top;' - lyrics = u'%s %s' % (align, valign) + lyrics = u'display:table-cell; %s %s' % (align, valign) if theme.display_outline: lyricscommon += u' letter-spacing: 1px;' outline = u'-webkit-text-stroke: %sem %s; ' % \ From 96737c0bc0f936daa2183c40db9dbba1d93d8ad1 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 2 Sep 2010 21:41:24 +0100 Subject: [PATCH 4/6] Use QtGraphicsWebview. Reduce div count where possible --- openlp/core/lib/htmlbuilder.py | 223 +++++++++++++++++++++------------ openlp/core/ui/maindisplay.py | 7 +- 2 files changed, 150 insertions(+), 80 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index c5b5088c4..7d283ae8c 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -24,6 +24,8 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +from PyQt4 import QtWebKit + from openlp.core.lib import image_to_byte HTMLSRC = u""" @@ -39,7 +41,7 @@ HTMLSRC = u""" body { background-color: black; } -.dim { +.size { position: absolute; left: 0px; top: 0px; @@ -51,6 +53,9 @@ body { background-color: black; display: none; } +#image { + z-index:1; +} #video { z-index:2; } @@ -136,8 +141,12 @@ body { } document.getElementById('black').style.display = black; document.getElementById('lyricsmain').style.visibility = lyrics; - document.getElementById('lyricsoutline').style.visibility = lyrics; - document.getElementById('lyricsshadow').style.visibility = lyrics; + outline = document.getElementById('lyricsoutline') + if(outline) + outline.style.visibility = lyrics; + shadow = document.getElementById('lyricsshadow') + if(shadow) + shadow.style.visibility = lyrics; document.getElementById('footer').style.visibility = lyrics; var vid = document.getElementById('video'); if(vid.src != ''){ @@ -193,7 +202,17 @@ body { } function text_fade(id, newtext){ + /* + Using -webkit-transition: opacity 1s linear; would have been preferred + but it isn't currently quick enough when animating multiple layers of + large areas of large text. Therefore do it manually as best we can. + Hopefully in the future we can revisit and do more interesting + transitions using -webkit-transition and -webkit-transform. + However we need to ensure interrupted transitions (quickly change 2 + slides) still looks pretty and is zippy. + */ var text = document.getElementById(id); + if(text==null) return; if(!transition){ text.innerHTML = newtext; return; @@ -213,37 +232,19 @@ body { var text = document.getElementById('lyricsmain'); return getComputedStyle(text, '').opacity; } + function show_text_complete(){ return (text_opacity()==1); } - -
-
-
-
-
-
-
-
-
- + + +%s - -
- +
+ """ @@ -258,7 +259,13 @@ def build_html(item, screen, alert, islive): Current display information `alert` Alert display display information + `islive` + Item is going live, rather than preview/theme building """ + try: + webkitvers = float(QtWebKit.qWebKitVersion()) + except AttributeError: + webkitvers = 0 width = screen[u'size'].width() height = screen[u'size'].height() theme = item.themedata @@ -267,83 +274,143 @@ def build_html(item, screen, alert, islive): else: image = u'' html = HTMLSRC % (width, height, - build_alert(alert, width), - build_footer(item), - build_lyrics(item), + build_alert_css(alert, width), + build_footer_css(item), + build_lyrics_css(item, webkitvers), u'true' if theme and theme.display_slideTransition and islive \ else u'false', - image) + image, + build_lyrics_html(item, webkitvers)) return html -def build_lyrics(item): +def build_lyrics_css(item, webkitvers): """ - Build the video display div + Build the video display css `item` Service Item containing theme and location information + + `webkitvers` + The version of qtwebkit we're using + """ style = """ - .lyricscommon { position: absolute; %s } - .lyricstable { z-index:4; %s } - .lyricsoutlinetable { z-index:3; %s } - .lyricsshadowtable { z-index:2; %s } - .lyrics { %s } - .lyricsoutline { %s } - .lyricsshadow { %s } +.lyricstable { + z-index:4; + position: absolute; + display: table; + %s +} +.lyricscell { + display:table-cell; + word-wrap: break-word; + %s +} +.lyricsmain { +%s +} +.lyricsoutline { +%s +} +.lyricsshadow { +%s +} """ theme = item.themedata - lyricscommon = u'' lyricstable = u'' - outlinetable = u'' - shadowtable = u'' lyrics = u'' - outline = u'display: none;' - shadow = u'display: none;' + lyricsmain = u'' + outline = u'' + shadow = u'' if theme: - lyricscommon = u'display: table; width: %spx; height: %spx; word-wrap: break-word; ' \ - u'font-family: %s; font-size: %spt; color: %s; line-height: %d%%;' \ - % (item.main.width(), item.main.height(), theme.font_main_name, - theme.font_main_proportion, theme.font_main_color, - 100 + int(theme.font_main_line_adjustment)) lyricstable = u'left: %spx; top: %spx;' % \ (item.main.x(), item.main.y()) - outlinetable = u'left: %spx; top: %spx;' % \ - (item.main.x(), item.main.y()) - shadowtable = u'left: %spx; top: %spx;' % \ - (item.main.x() + float(theme.display_shadow_size), - item.main.y() + float(theme.display_shadow_size)) - align = u'' if theme.display_horizontalAlign == 2: - align = u'text-align:center;' + align = u'center' elif theme.display_horizontalAlign == 1: - align = u'text-align:right;' + align = u'right' else: - align = u'text-align:left;' + align = u'left' if theme.display_verticalAlign == 2: - valign = u'vertical-align:bottom;' + valign = u'bottom' elif theme.display_verticalAlign == 1: - valign = u'vertical-align:middle;' + valign = u'middle' else: - valign = u'vertical-align:top;' - lyrics = u'display:table-cell; %s %s' % (align, valign) + valign = u'top' + lyrics = u'width: %spx; height: %spx; text-align: %s; ' \ + 'vertical-align: %s; font-family: %s; font-size: %spt; ' \ + 'color: %s; line-height: %d%%;' % \ + (item.main.width(), item.main.height(), align, valign, + theme.font_main_name, theme.font_main_proportion, + theme.font_main_color, 100 + int(theme.font_main_line_adjustment)) + # For performance reasons we want to show as few DIV's as possible, + # especially when animating/transitions. + # However some bugs in older versions of qtwebkit mean we need to + # perform workarounds and add extra divs. Only do these when needed. + # + # Before 533.3 the webkit-text-fill colour wasn't displayed, only the + # stroke (outline) color. So put stroke layer underneath the main text. + # + # Before 534.4 the webkit-text-stroke was sometimes out of alignment + # with the fill, or normal text. letter-spacing=1 is workaround + # https://bugs.webkit.org/show_bug.cgi?id=44403 + # + # Before 534.4 the text-shadow didn't get displayed when + # webkit-text-stroke was used. So use an offset text layer underneath. + # https://bugs.webkit.org/show_bug.cgi?id=19728 if theme.display_outline: - lyricscommon += u' letter-spacing: 1px;' - outline = u'-webkit-text-stroke: %sem %s; ' % \ + if webkitvers < 534.3: + lyrics += u' letter-spacing: 1px;' + outline = u' -webkit-text-stroke: %sem %s; ' \ + '-webkit-text-fill-color: %s; ' % \ (float(theme.display_outline_size) / 16, - theme.display_outline_color) - if theme.display_shadow: + theme.display_outline_color, theme.font_main_color) + if webkitvers >= 533.3: + lyricsmain += outline + if theme.display_shadow and webkitvers < 534.3: shadow = u'-webkit-text-stroke: %sem %s; ' \ - u'-webkit-text-fill-color: %s; ' % \ + u'-webkit-text-fill-color: %s; ' \ + u' padding-left: %spx; padding-top: %spx' % \ (float(theme.display_outline_size) / 16, - theme.display_shadow_color, theme.display_shadow_color) - else: - if theme.display_shadow: - shadow = u'color: %s;' % (theme.display_shadow_color) - lyrics_html = style % (lyricscommon, lyricstable, outlinetable, - shadowtable, lyrics, outline, shadow) - return lyrics_html + theme.display_shadow_color, theme.display_shadow_color, + theme.display_shadow_size, theme.display_shadow_size) + if theme.display_shadow and \ + (not theme.display_outline or webkitvers >= 534.3): + lyricsmain += u' text-shadow: %s %spx %spx;' % \ + (theme.display_shadow_color, theme.display_shadow_size, + theme.display_shadow_size) + lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow) + return lyrics_css + +def build_lyrics_html(item, webkitvers): + """ + Build the HTML required to show the lyrics -def build_footer(item): + `item` + Service Item containing theme and location information + + `webkitvers` + The version of qtwebkit we're using + """ + # Bugs in some versions of QtWebKit mean we sometimes need additional + # divs for outline and shadow, since the CSS doesn't work. + # To support vertical alignment middle and bottom, nested div's using + # display:table/display:table-cell are required for each lyric block. + lyrics = u'' + theme = item.themedata + if webkitvers < 534.4 and theme and theme.display_outline: + lyrics += u'
' \ + u'
' \ + u'
' + if webkitvers < 533.3: + lyrics += u'
' \ + u'
' \ + u'
' + lyrics += u'
' \ + u'
' + return lyrics + +def build_footer_css(item): """ Build the display of the item footer @@ -374,7 +441,7 @@ def build_footer(item): theme.font_footer_proportion, theme.font_footer_color, align) return lyrics_html -def build_alert(alertTab, width): +def build_alert_css(alertTab, width): """ Build the display of the footer @@ -382,7 +449,7 @@ def build_alert(alertTab, width): Details from the Alert tab for fonts etc """ style = """ - width: %s; + width: %spx; vertical-align: %s; font-family: %s; font-size: %spt; diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index c985434c1..4f2ea6df6 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -115,8 +115,11 @@ class MainDisplay(DisplayWidget): self.screen = self.screens.current self.setVisible(False) self.setGeometry(self.screen[u'size']) - self.webView = QtWebKit.QWebView(self) - self.webView.setGeometry(0, 0, self.screen[u'size'].width(), \ + self.scene = QtGui.QGraphicsScene() + self.setScene(self.scene) + self.webView = QtWebKit.QGraphicsWebView() + self.scene.addItem(self.webView) + self.webView.resize(self.screen[u'size'].width(), \ self.screen[u'size'].height()) self.page = self.webView.page() self.frame = self.page.mainFrame() From 8be66a0e6f1420613ece8c887835eec2a00f68fe Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 2 Sep 2010 22:24:44 +0100 Subject: [PATCH 5/6] A bit of python crept into the javascript --- openlp/core/lib/htmlbuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 7d283ae8c..dffa5deec 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -142,10 +142,10 @@ body { document.getElementById('black').style.display = black; document.getElementById('lyricsmain').style.visibility = lyrics; outline = document.getElementById('lyricsoutline') - if(outline) + if(outline!=null) outline.style.visibility = lyrics; shadow = document.getElementById('lyricsshadow') - if(shadow) + if(shadow!=null) shadow.style.visibility = lyrics; document.getElementById('footer').style.visibility = lyrics; var vid = document.getElementById('video'); From e292748b838c1cb44f2b14297cd152c7c65de8f5 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 3 Sep 2010 19:30:56 +0100 Subject: [PATCH 6/6] Colour and poss blank verse fix? --- openlp/core/lib/__init__.py | 36 +++++++++++++++++----------------- openlp/core/lib/htmlbuilder.py | 16 ++++++++------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index b76179c2c..721b6ae23 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -39,40 +39,40 @@ log = logging.getLogger(__name__) html_expands = [] html_expands.append({u'desc':u'Red', u'start tag':u'{r}', \ - u'start html':u'', \ - u'end tag':u'{/r}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/r}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Black', u'start tag':u'{b}', \ - u'start html':u'', \ - u'end tag':u'{/b}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/b}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Blue', u'start tag':u'{bl}', \ - u'start html':u'', \ - u'end tag':u'{/bl}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/bl}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Yellow', u'start tag':u'{y}', \ - u'start html':u'', \ - u'end tag':u'{/y}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/y}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Green', u'start tag':u'{g}', \ - u'start html':u'', \ - u'end tag':u'{/g}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/g}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Pink', u'start tag':u'{pk}', \ - u'start html':u'', \ - u'end tag':u'{/pk}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/pk}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Orange', u'start tag':u'{o}', \ - u'start html':u'', \ - u'end tag':u'{/o}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/o}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Purple', u'start tag':u'{pp}', \ - u'start html':u'', \ - u'end tag':u'{/pp}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/pp}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'White', u'start tag':u'{w}', \ - u'start html':u'', \ - u'end tag':u'{/w}', u'end html':u'', \ + u'start html':u'', \ + u'end tag':u'{/w}', u'end html':u'', \ u'protected':False}) html_expands.append({u'desc':u'Superscript', u'start tag':u'{su}', \ u'start html':u'', \ diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index dffa5deec..d03b7f7cc 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -217,11 +217,12 @@ body { text.innerHTML = newtext; return; } - if(text.style.opacity=='') text.style.opacity = 1; if(newtext==text.innerHTML){ text.style.opacity = parseFloat(text.style.opacity) + 0.3; + if(text.style.opacity>0.7) + text.style.opacity = 1; } else { - text.style.opacity -= 0.3; + text.style.opacity = parseFloat(text.style.opacity) - 0.3; if(text.style.opacity<=0.1){ text.innerHTML = newtext; } @@ -400,14 +401,15 @@ def build_lyrics_html(item, webkitvers): theme = item.themedata if webkitvers < 534.4 and theme and theme.display_outline: lyrics += u'
' \ - u'
' \ - u'
' + u'
' if webkitvers < 533.3: lyrics += u'
' \ - u'
' \ - u'
' + u'
' lyrics += u'
' \ - u'
' + u'
' return lyrics def build_footer_css(item):