forked from openlp/openlp
- use html5 for transitions
- added test *cough* - fixed bug #1147307 (Transtion + fast slide changes + ESC causes screen to open again) bzr-revno: 2200 Fixes: https://launchpad.net/bugs/1147307
This commit is contained in:
commit
88fb52ffba
@ -127,7 +127,7 @@ sup {
|
|||||||
document.getElementById('footer').innerHTML = footertext;
|
document.getElementById('footer').innerHTML = footertext;
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_text(newtext){
|
function show_text(new_text){
|
||||||
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
||||||
if(timer != null)
|
if(timer != null)
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
@ -142,57 +142,47 @@ sup {
|
|||||||
if(outline != null)
|
if(outline != null)
|
||||||
txt = outline;
|
txt = outline;
|
||||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||||
newtext = newtext.replace(/(\s| )+(?![^<]*>)/g,
|
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||||
function(match) {
|
function(match) {
|
||||||
return '</span>' + match + '<span>';
|
return '</span>' + match + '<span>';
|
||||||
});
|
});
|
||||||
newtext = '<span>' + newtext + '</span>';
|
new_text = '<span>' + new_text + '</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text_fade('lyricsmain', newtext);
|
text_fade('lyricsmain', new_text);
|
||||||
text_fade('lyricsoutline', newtext);
|
text_fade('lyricsoutline', new_text);
|
||||||
text_fade('lyricsshadow', newtext.replace(match, ''));
|
text_fade('lyricsshadow', new_text.replace(match, ''));
|
||||||
if(text_opacity() == 1) return;
|
|
||||||
timer = setTimeout(function(){
|
|
||||||
show_text(newtext);
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function text_fade(id, newtext){
|
function text_fade(id, new_text){
|
||||||
/*
|
/*
|
||||||
Using -webkit-transition: opacity 1s linear; would have been preferred
|
Show the text.
|
||||||
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);
|
var text = document.getElementById(id);
|
||||||
if(text == null) return;
|
if(text == null) return;
|
||||||
if(!transition){
|
if(!transition){
|
||||||
text.innerHTML = newtext;
|
text.innerHTML = new_text;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(newtext == text.innerHTML){
|
// Fade text out. 0.2 to minimize the time "nothing" is shown on the screen.
|
||||||
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
|
text.style.opacity = '0.2';
|
||||||
if(text.style.opacity > 0.7)
|
// Fade new text in after the old text has finished fading out.
|
||||||
text.style.opacity = 1;
|
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||||
} else {
|
|
||||||
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
|
|
||||||
if(text.style.opacity <= 0.1){
|
|
||||||
text.innerHTML = newtext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function text_opacity(){
|
function _show_text(text, new_text) {
|
||||||
var text = document.getElementById('lyricsmain');
|
/*
|
||||||
return getComputedStyle(text, '').opacity;
|
Helper function to show the new_text delayed.
|
||||||
|
*/
|
||||||
|
text.innerHTML = new_text;
|
||||||
|
text.style.opacity = '1';
|
||||||
|
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||||
|
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||||
|
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_text_complete(){
|
function show_text_completed(){
|
||||||
return (text_opacity() == 1);
|
return (timer == null);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@ -336,6 +326,7 @@ def build_lyrics_css(item, webkit_ver):
|
|||||||
.lyricscell {
|
.lyricscell {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
-webkit-transition: opacity 0.4s ease;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
.lyricsmain {
|
.lyricsmain {
|
||||||
|
@ -347,13 +347,14 @@ class MainDisplay(Display):
|
|||||||
Generates a preview of the image displayed.
|
Generates a preview of the image displayed.
|
||||||
"""
|
"""
|
||||||
log.debug(u'preview for %s', self.isLive)
|
log.debug(u'preview for %s', self.isLive)
|
||||||
|
was_visible = self.isVisible()
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# We must have a service item to preview.
|
# We must have a service item to preview.
|
||||||
if self.isLive and hasattr(self, u'serviceItem'):
|
if self.isLive and hasattr(self, u'serviceItem'):
|
||||||
# Wait for the fade to finish before geting the preview.
|
# Wait for the fade to finish before geting the preview.
|
||||||
# Important otherwise preview will have incorrect text if at all!
|
# Important otherwise preview will have incorrect text if at all!
|
||||||
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
|
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
|
||||||
while self.frame.evaluateJavaScript(u'show_text_complete()') == u'false':
|
while not self.frame.evaluateJavaScript(u'show_text_completed()'):
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# Wait for the webview to update before getting the preview.
|
# Wait for the webview to update before getting the preview.
|
||||||
# Important otherwise first preview will miss the background !
|
# Important otherwise first preview will miss the background !
|
||||||
@ -363,7 +364,8 @@ class MainDisplay(Display):
|
|||||||
if self.isLive:
|
if self.isLive:
|
||||||
if self.hideMode:
|
if self.hideMode:
|
||||||
self.hide_display(self.hideMode)
|
self.hide_display(self.hideMode)
|
||||||
else:
|
# Only continue if the visibility wasn't changed during method call.
|
||||||
|
elif was_visible == self.isVisible():
|
||||||
# Single screen active
|
# Single screen active
|
||||||
if self.screens.display_count == 1:
|
if self.screens.display_count == 1:
|
||||||
# Only make visible if setting enabled.
|
# Only make visible if setting enabled.
|
||||||
|
@ -7,7 +7,7 @@ from datetime import datetime, timedelta
|
|||||||
from mock import MagicMock, patch
|
from mock import MagicMock, patch
|
||||||
|
|
||||||
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
|
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
|
||||||
image_to_byte, check_item_selected, validate_thumb, create_separated_list
|
image_to_byte, check_item_selected, validate_thumb, create_separated_list, expand_tags
|
||||||
|
|
||||||
class TestLib(TestCase):
|
class TestLib(TestCase):
|
||||||
|
|
||||||
@ -299,6 +299,45 @@ class TestLib(TestCase):
|
|||||||
MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message')
|
MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message')
|
||||||
assert not result, u'The result should be False'
|
assert not result, u'The result should be False'
|
||||||
|
|
||||||
|
def expand_tags_test(self):
|
||||||
|
"""
|
||||||
|
Test the expand_tags() method.
|
||||||
|
"""
|
||||||
|
with patch(u'openlp.core.lib.FormattingTags.get_html_tags') as mocked_get_tags:
|
||||||
|
# GIVEN: Mocked get_html_tags() method.
|
||||||
|
mocked_get_tags.return_value = [
|
||||||
|
{
|
||||||
|
u'desc': u'Black',
|
||||||
|
u'start tag': u'{b}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:black">',
|
||||||
|
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
},
|
||||||
|
{
|
||||||
|
u'desc': u'Yellow',
|
||||||
|
u'start tag': u'{y}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
|
||||||
|
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
},
|
||||||
|
{
|
||||||
|
u'desc': u'Green',
|
||||||
|
u'start tag': u'{g}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:green">',
|
||||||
|
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
}
|
||||||
|
]
|
||||||
|
string_to_pass = u'{b}black{/b}{y}yellow{/y}'
|
||||||
|
wanted_string = u'<span style="-webkit-text-fill-color:black">black</span>' + \
|
||||||
|
'<span style="-webkit-text-fill-color:yellow">yellow</span>'
|
||||||
|
|
||||||
|
# WHEN: Replace the tags.
|
||||||
|
result_string = expand_tags(string_to_pass)
|
||||||
|
|
||||||
|
# THEN: The strings should be identical.
|
||||||
|
assert result_string == wanted_string, u'The strings should be identical.'
|
||||||
|
|
||||||
def validate_thumb_file_does_not_exist_test(self):
|
def validate_thumb_file_does_not_exist_test(self):
|
||||||
"""
|
"""
|
||||||
Test the validate_thumb() function when the thumbnail does not exist
|
Test the validate_thumb() function when the thumbnail does not exist
|
||||||
|
Loading…
Reference in New Issue
Block a user