(experimental) attempt to imporve renderer (to be fixed)

This commit is contained in:
Andreas Preikschat 2012-05-20 20:26:24 +02:00
parent 6e502554a6
commit 060718be32
6 changed files with 88 additions and 112 deletions

View File

@ -59,12 +59,12 @@ class Renderer(object):
"""
Initialise the renderer.
``imageManager``
A imageManager instance which takes care of e. g. caching and resizing
images.
``imageManager``
A imageManager instance which takes care of e. g. caching and
resizing images.
``themeManager``
The themeManager instance, used to get the current theme details.
``themeManager``
The themeManager instance, used to get the current theme details.
"""
log.debug(u'Initialisation started')
self.themeManager = themeManager
@ -73,54 +73,85 @@ class Renderer(object):
self.service_theme = u''
self.theme_level = u''
self.override_background = None
self.theme_data = None
self.bg_frame = None
self.force_page = False
self.display = MainDisplay(None, self.imageManager, False, self)
self.display.setup()
self.theme_dimensions = {}
self._calculate_default()
def update_display(self):
"""
Updates the renderer's information about the current screen.
"""
log.debug(u'Update Display')
self._calculate_default()
if self.display:
self.display.close()
self.display = MainDisplay(None, self.imageManager, False, self)
self.display.setup()
self.bg_frame = None
self.theme_data = None
self._calculate_default()
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
def set_theme(self, theme_name):
"""
"""
if theme_name not in self.theme_dimensions:
theme_data = self.themeManager.getThemeData(theme_name)
main_rect = self.get_main_rectangle(theme_data)
footer_rect = self.get_footer_rectangle(theme_data)
self.theme_dimensions[theme_name] = [theme_data, main_rect, footer_rect]
else:
theme_data, main_rect, footer_rect = self.theme_dimensions[theme_name]
# if No file do not update cache
if theme_data.background_filename:
self.imageManager.add_image(theme_data.theme_name,
theme_data.background_filename, u'theme',
QtGui.QColor(theme_data.background_border_color))
def post_render(self, override_theme_data):
"""
"""
# Just assume we use the global theme.
theme_to_use = self.global_theme
if self.theme_level == ThemeLevel.Service:
# When the theme level is at Service and we actually have a service
# theme then use it.
if self.service_theme:
theme_to_use = self.service_theme
elif self.theme_level == ThemeLevel.Song and self.item_theme:
theme_to_use = self.item_theme
theme_data, main_rect, footer_rect = self.theme_dimensions[theme_to_use]
if override_theme_data:
theme_data = override_theme_data
self._set_text_rectangle(theme_data, main_rect, footer_rect)
return theme_data, self._rect, self._rect_footer
def set_theme_level(self, theme_level):
"""
"""
self.theme_level = theme_level
def set_global_theme(self, global_theme_name):
"""
Set the global-level theme and the theme level.
``global_theme``
The global-level theme to be set.
``theme_level``
Defaults to ``ThemeLevel.Global``. The theme level, can be
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
``ThemeLevel.Song``.
"""
self.global_theme = global_theme
self.theme_level = theme_level
self.global_theme_data = \
self.themeManager.getThemeData(self.global_theme)
self.theme_data = None
self.set_theme(global_theme_name)
self.global_theme = global_theme_name
def set_service_theme(self, service_theme):
def set_service_theme(self, service_theme_name):
"""
Set the service-level theme.
``service_theme``
The service-level theme to be set.
"""
self.service_theme = service_theme
self.theme_data = None
self.set_theme(service_theme_name)
self.service_theme = service_theme_name
def set_override_theme(self, override_theme, override_levels=False):
def set_override_theme(self, override_theme_name):
"""
Set the appropriate theme depending on the theme level.
Called by the service item when building a display frame
@ -128,47 +159,9 @@ class Renderer(object):
``override_theme``
The name of the song-level theme. None means the service
item wants to use the given value.
``override_levels``
Used to force the theme data passed in to be used.
"""
log.debug(u'set override theme to %s', override_theme)
theme_level = self.theme_level
if override_levels:
theme_level = ThemeLevel.Song
if theme_level == ThemeLevel.Global:
theme = self.global_theme
elif theme_level == ThemeLevel.Service:
if self.service_theme == u'':
theme = self.global_theme
else:
theme = self.service_theme
else:
# Images have a theme of -1
if override_theme and override_theme != -1:
theme = override_theme
elif theme_level == ThemeLevel.Song or \
theme_level == ThemeLevel.Service:
if self.service_theme == u'':
theme = self.global_theme
else:
theme = self.service_theme
else:
theme = self.global_theme
log.debug(u'theme is now %s', theme)
# Force the theme to be the one passed in.
if override_levels:
self.theme_data = override_theme
else:
self.theme_data = self.themeManager.getThemeData(theme)
self._calculate_default()
self._build_text_rectangle(self.theme_data)
# if No file do not update cache
if self.theme_data.background_filename:
self.imageManager.add_image(self.theme_data.theme_name,
self.theme_data.background_filename, u'theme',
QtGui.QColor(self.theme_data.background_border_color))
return self._rect, self._rect_footer
self.set_theme(override_theme_name)
self.item_theme = override_theme_name
def generate_preview(self, theme_data, force_page=False):
"""
@ -183,11 +176,10 @@ class Renderer(object):
log.debug(u'generate preview')
# save value for use in format_slide
self.force_page = force_page
# set the default image size for previews
self._calculate_default()
# build a service item to generate preview
serviceItem = ServiceItem()
serviceItem.theme = theme_data
serviceItem.theme = theme_data.theme_name
#self.set_override_theme(theme_data)
if self.force_page:
# make big page for theme edit dialog to get line count
serviceItem.add_from_text(u'', VERSE_FOR_LINE_COUNT)
@ -196,14 +188,12 @@ class Renderer(object):
serviceItem.add_from_text(u'', VERSE)
serviceItem.renderer = self
serviceItem.raw_footer = FOOTER
serviceItem.render(True)
serviceItem.render(theme_data)
if not self.force_page:
self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)
self.display.text(raw_html)
preview = self.display.preview()
# Reset the real screen size for subsequent render requests
self._calculate_default()
return preview
self.force_page = False
@ -303,32 +293,19 @@ class Renderer(object):
# 90% is start of footer
self.footer_start = int(self.height * 0.90)
def _build_text_rectangle(self, theme):
"""
Builds a text block using the settings in ``theme``
and the size of the display screen.height.
Note the system has a 10 pixel border round the screen
``theme``
The theme to build a text block for.
"""
log.debug(u'_build_text_rectangle')
main_rect = self.get_main_rectangle(theme)
footer_rect = self.get_footer_rectangle(theme)
self._set_text_rectangle(main_rect, footer_rect)
def get_main_rectangle(self, theme):
def get_main_rectangle(self, theme_data):
"""
Calculates the placement and size of the main rectangle.
``theme``
``theme_data``
The theme information
"""
if not theme.font_main_override:
return QtCore.QRect(10, 0, self.width - 20, self.footer_start)
if not theme_data.font_main_override:
return QtCore.QRect(10, 0, self.width, self.footer_start)
else:
return QtCore.QRect(theme.font_main_x, theme.font_main_y,
theme.font_main_width - 1, theme.font_main_height - 1)
return QtCore.QRect(theme_data.font_main_x, theme_data.font_main_y,
theme_data.font_main_width - 1, theme_data.font_main_height - 1)
def get_footer_rectangle(self, theme):
"""
@ -345,7 +322,7 @@ class Renderer(object):
theme.font_footer_y, theme.font_footer_width - 1,
theme.font_footer_height - 1)
def _set_text_rectangle(self, rect_main, rect_footer):
def _set_text_rectangle(self, theme_data, rect_main, rect_footer):
"""
Sets the rectangle within which text should be rendered.
@ -360,9 +337,9 @@ class Renderer(object):
self._rect_footer = rect_footer
self.page_width = self._rect.width()
self.page_height = self._rect.height()
if self.theme_data.font_main_shadow:
self.page_width -= int(self.theme_data.font_main_shadow_size)
self.page_height -= int(self.theme_data.font_main_shadow_size)
if theme_data.font_main_shadow:
self.page_width -= int(theme_data.font_main_shadow_size)
self.page_height -= int(theme_data.font_main_shadow_size)
self.web = QtWebKit.QWebView()
self.web.setVisible(False)
self.web.resize(self.page_width, self.page_height)
@ -380,8 +357,8 @@ class Renderer(object):
</script><style>*{margin: 0; padding: 0; border: 0;}
#main {position: absolute; top: 0px; %s %s}</style></head><body>
<div id="main"></div></body></html>""" % \
(build_lyrics_format_css(self.theme_data, self.page_width,
self.page_height), build_lyrics_outline_css(self.theme_data))
(build_lyrics_format_css(theme_data, self.page_width,
self.page_height), build_lyrics_outline_css(theme_data))
self.web.setHtml(html)
self.empty_height = self.web_frame.contentsSize().height()

View File

@ -164,13 +164,14 @@ class ServiceItem(object):
obtains the display information from the renderer. At this point all
slides are built for the given display size.
"""
import time
import datetime
start = time.time()
log.debug(u'Render called')
self._display_frames = []
self.bg_image_bytes = None
theme = self.theme if self.theme else None
self.main, self.footer = \
self.renderer.set_override_theme(theme, use_override)
self.themedata = self.renderer.theme_data
self.renderer.set_override_theme(self.theme)
self.themedata, self.main, self.footer = self.renderer.post_render(use_override)
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
for slide in self._raw_frames:
@ -196,6 +197,7 @@ class ServiceItem(object):
if self.raw_footer is None:
self.raw_footer = []
self.foot_text = u'<br>'.join(filter(None, self.raw_footer))
print unicode(datetime.timedelta(seconds=(time.time() - start)))
def add_from_image(self, path, title, background=None):
"""

View File

@ -863,7 +863,7 @@ class SlideController(Controller):
image = self.imageManager.get_image(frame[u'title'])
label.setPixmap(QtGui.QPixmap.fromImage(image))
self.previewListWidget.setCellWidget(framenumber, 0, label)
slideHeight = width * self.parent().renderer.screen_ratio
slideHeight = width * (1 / self.ratio)
row += 1
self.slideList[unicode(row)] = row - 1
text.append(unicode(row))

View File

@ -250,6 +250,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Generate layout preview and display the form.
"""
self.updateTheme()
screen_size = self.screens.current[u'size']
width = self.thememanager.mainwindow.renderer.width
height = self.thememanager.mainwindow.renderer.height
pixmap = QtGui.QPixmap(width, height)

View File

@ -151,8 +151,8 @@ class ThemesTab(SettingsTab):
settings.setValue(u'theme level', QtCore.QVariant(self.theme_level))
settings.setValue(u'global theme', QtCore.QVariant(self.global_theme))
settings.endGroup()
self.mainwindow.renderer.set_global_theme(
self.global_theme, self.theme_level)
self.mainwindow.renderer.set_global_theme(self.global_theme)
self.mainwindow.renderer.set_theme_level(self.theme_level)
Receiver.send_message(u'theme_update_global', self.global_theme)
def postSetUp(self):
@ -169,8 +169,8 @@ class ThemesTab(SettingsTab):
def onDefaultComboBoxChanged(self, value):
self.global_theme = unicode(self.DefaultComboBox.currentText())
self.mainwindow.renderer.set_global_theme(
self.global_theme, self.theme_level)
self.mainwindow.renderer.set_global_theme(self.global_theme)
self.mainwindow.renderer.set_theme_level(self.theme_level)
self.__previewGlobalTheme()
def updateThemeList(self, theme_list):
@ -189,8 +189,8 @@ class ThemesTab(SettingsTab):
self.DefaultComboBox.clear()
self.DefaultComboBox.addItems(theme_list)
find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme)
self.mainwindow.renderer.set_global_theme(
self.global_theme, self.theme_level)
self.mainwindow.renderer.set_global_theme(self.global_theme)
self.mainwindow.renderer.set_theme_level(self.theme_level)
if self.global_theme is not u'':
self.__previewGlobalTheme()

View File

@ -197,9 +197,6 @@ class CustomMediaItem(MediaManagerItem):
def generateSlideData(self, service_item, item=None, xmlVersion=False,
remote=False):
raw_footer = []
slide = None
theme = None
item_id = self._getIdOfItemToGenerate(item, self.remoteCustom)
service_item.add_capability(ItemCapabilities.CanEdit)
service_item.add_capability(ItemCapabilities.CanPreview)
@ -207,6 +204,7 @@ class CustomMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.CanSoftBreak)
customSlide = self.plugin.manager.get_object(CustomSlide, item_id)
title = customSlide.title
service_item.title = title
credit = customSlide.credits
service_item.edit_id = item_id
theme = customSlide.theme_name
@ -215,15 +213,13 @@ class CustomMediaItem(MediaManagerItem):
customXML = CustomXMLParser(customSlide.text)
verseList = customXML.get_verses()
raw_slides = [verse[1] for verse in verseList]
service_item.title = title
for slide in raw_slides:
service_item.add_from_text(slide[:30], slide)
if QtCore.QSettings().value(self.settingsSection + u'/display footer',
QtCore.QVariant(True)).toBool() or credit:
raw_footer.append(title + u' ' + credit)
service_item.raw_footer.append(u' '.join([title, credit]))
else:
raw_footer.append(u'')
service_item.raw_footer = raw_footer
service_item.raw_footer.append(u'')
return True
def onSearchTextButtonClicked(self):