diff --git a/openlp/core/display/html/display.js b/openlp/core/display/html/display.js index e0bd72144..34b6c0951 100644 --- a/openlp/core/display/html/display.js +++ b/openlp/core/display/html/display.js @@ -66,7 +66,8 @@ var TransitionState = { */ var AnimationState = { NoAnimation: "noAnimation", - ScrollingAnimation: "scrollingAnimation" + ScrollingText: "scrollingText", + NonScrollingText: "noScrollingText" }; /** @@ -433,29 +434,16 @@ var Display = { } Display.doEntranceTransition(settings); - - // TODO: Add functionality for no scroll - alertBackground.addEventListener('transitionend', function (e) { + + alertBackground.addEventListener('transitionend', function(e) { e.stopPropagation(); - if (Display._transitionState === TransitionState.EntranceTransition) { - alertText.style.visibility = "visible"; - alertText.classList.add("horizontal-scroll-animation"); - Display._animationState = AnimationState.ScrollingAnimation; - Display._transitionState = TransitionState.NoTransition - } - else if (Display._transitionState === TransitionState.ExitTransition) { - Display._transitionState = TransitionState.NoTransition; - alertText.style.visibility = "hidden"; - alertBackground.classList = ""; - alertBackground.classList.add("normal"); - } + Display.transitionEndEvent(settings); }); - alertBackground.addEventListener('animationend', function (e) { + alertText.addEventListener('animationend', function (e) { e.stopPropagation(); - if (Display._animationState === AnimationState.ScrollingAnimation) { - console.debug("Scrolling animation finished"); - alertText.classList.remove("horizontal-scroll-animation"); + if (Display._animationState === AnimationState.ScrollingText) { + alertText.style.animation = ""; alertText.style.visibility = "hidden"; Display._animationState = AnimationState.NoAnimation; Display.doExitTransition(); @@ -484,7 +472,7 @@ var Display = { } alertText.style.color = settings.font_color; alertText.style.fontFamily = settings.font_face; - alertText.style.fontSize = settings.font_size + "pt"; + alertText.style.fontSize = settings.font_size + "pt"; alertBackground.style.backgroundColor = settings.background_color; if (this._alertState === AlertState.DisplayingFromQueue) { @@ -516,7 +504,7 @@ var Display = { /** * Display the next alert in the queue */ - getNextAlert: function () { + getNextAlert: function () { if (Display._alerts.length > 0) { var alertObject = JSON.parse(this._alerts.shift()); this._alertState = AlertState.DisplayingFromQueue; @@ -526,6 +514,39 @@ var Display = { return null; } }, + /** + * Set text styles and animations when transitions are are completed + * @param {event} event - The event that has occured + * @param {json} settings object - The settings to use for the animation + */ + transitionEndEvent: function (settings) { + var alertBackground = $("#alert-background")[0]; + var alertText = $("#alert")[0]; + if (Display._transitionState === TransitionState.EntranceTransition) { + alertText.style.visibility = "visible"; + if (settings.scroll) { + var animationSettings = "alert-scrolling-text " + settings.timeout + + "s linear 0s " + settings.repeat + " normal"; + alertText.style.animation = animationSettings; + Display._animationState = AnimationState.ScrollingText; + } + else { + Display._animationState = AnimationState.NonScrollingText; + setTimeout (function () { + alertText.style.visibility = "hidden"; + Display._animationState = AnimationState.NoAnimation; + Display.doExitTransition(); + }, settings.timeout * 1000); + } + Display._transitionState = TransitionState.NoTransition + } + else if (Display._transitionState === TransitionState.ExitTransition) { + Display._transitionState = TransitionState.NoTransition; + alertText.style.visibility = "hidden"; + alertBackground.classList = ""; + alertBackground.classList.add("normal"); + } + }, /** * Add a slides. If the slide exists but the HTML is different, update the slide. * @param {string} verse - The verse number, e.g. "v1" diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index e1213aac1..26f2ae9b9 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -125,7 +125,9 @@ __default_settings__ = { 'alerts/location': AlertLocation.Bottom, 'alerts/background color': '#660000', 'alerts/font color': '#ffffff', - 'alerts/timeout': 5 + 'alerts/timeout': 10, + 'alerts/repeat': 1, + 'alerts/scroll': True } diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 4a673f865..8b79b80c5 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -97,7 +97,9 @@ class AlertsManager(QtCore.QObject, RegistryBase, LogMixin, RegistryProperties): 'font_face': Settings().value('alerts/font face'), 'font_size': Settings().value('alerts/font size'), 'font_color': rgb_font_color, - 'timeout': Settings().value('alerts/timeout') + 'timeout': Settings().value('alerts/timeout'), + 'repeat': Settings().value('alerts/repeat'), + 'scroll': Settings().value('alerts/scroll') } self.live_controller.displays[0].alert(text, json.dumps(alert_settings)) # Check to see if we have a timer running. diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index c1672b1df..a359c736f 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -47,35 +47,56 @@ class AlertsTab(SettingsTab): self.font_layout.addRow(self.font_label, self.font_combo_box) self.font_color_label = QtWidgets.QLabel(self.font_group_box) self.font_color_label.setObjectName('font_color_label') - self.color_layout = QtWidgets.QHBoxLayout() - self.color_layout.setObjectName('color_layout') self.font_color_button = ColorButton(self.font_group_box) self.font_color_button.setObjectName('font_color_button') - self.color_layout.addWidget(self.font_color_button) - self.color_layout.addSpacing(20) - self.background_color_label = QtWidgets.QLabel(self.font_group_box) - self.background_color_label.setObjectName('background_color_label') - self.color_layout.addWidget(self.background_color_label) - self.background_color_button = ColorButton(self.font_group_box) - self.background_color_button.setObjectName('background_color_button') - self.color_layout.addWidget(self.background_color_button) - self.font_layout.addRow(self.font_color_label, self.color_layout) + self.font_layout.addRow(self.font_color_label, self.font_color_button) self.font_size_label = QtWidgets.QLabel(self.font_group_box) self.font_size_label.setObjectName('font_size_label') self.font_size_spin_box = QtWidgets.QSpinBox(self.font_group_box) self.font_size_spin_box.setObjectName('font_size_spin_box') self.font_layout.addRow(self.font_size_label, self.font_size_spin_box) - self.timeout_label = QtWidgets.QLabel(self.font_group_box) + self.left_layout.addWidget(self.font_group_box) + # Background Settings + self.background_group_box = QtWidgets.QGroupBox(self.left_column) + self.background_group_box.setObjectName('background_group_box') + self.background_layout = QtWidgets.QFormLayout(self.background_group_box) + self.background_layout.setObjectName('background_settings_layout') + self.background_color_label = QtWidgets.QLabel(self.background_group_box) + self.background_color_label.setObjectName('background_color_label') + self.background_color_button = ColorButton(self.background_group_box) + self.background_color_button.setObjectName('background_color_button') + self.background_layout.addRow(self.background_color_label,self.background_color_button) + self.left_layout.addWidget(self.background_group_box) + # Scroll Settings + self.scroll_group_box = QtWidgets.QGroupBox(self.left_column) + self.scroll_group_box.setObjectName('scroll_group_box') + self.scroll_group_layout = QtWidgets.QFormLayout(self.scroll_group_box) + self.scroll_group_layout.setObjectName('scroll_group_layout') + self.scroll_check_box = QtWidgets.QCheckBox(self.scroll_group_box) + self.scroll_check_box.setObjectName('scroll_check_box') + self.scroll_group_layout.addRow(self.scroll_check_box) + self.repeat_label = QtWidgets.QLabel(self.scroll_group_box) + self.repeat_label.setObjectName('repeat_label') + self.repeat_spin_box = QtWidgets.QSpinBox(self.scroll_group_box) + self.repeat_spin_box.setObjectName('repeat_spin_box') + self.scroll_group_layout.addRow(self.repeat_label, self.repeat_spin_box) + self.left_layout.addWidget(self.scroll_group_box) + # Other Settings + self.settings_group_box = QtWidgets.QGroupBox(self.left_column) + self.settings_group_box.setObjectName('settings_group_box') + self.settings_layout = QtWidgets.QFormLayout(self.settings_group_box) + self.settings_layout.setObjectName('settings_layout') + self.timeout_label = QtWidgets.QLabel(self.settings_group_box) self.timeout_label.setObjectName('timeout_label') - self.timeout_spin_box = QtWidgets.QSpinBox(self.font_group_box) + self.timeout_spin_box = QtWidgets.QSpinBox(self.settings_group_box) self.timeout_spin_box.setMaximum(180) self.timeout_spin_box.setObjectName('timeout_spin_box') - self.font_layout.addRow(self.timeout_label, self.timeout_spin_box) + self.settings_layout.addRow(self.timeout_label, self.timeout_spin_box) self.vertical_label, self.vertical_combo_box = create_valign_selection_widgets(self.font_group_box) self.vertical_label.setObjectName('vertical_label') self.vertical_combo_box.setObjectName('vertical_combo_box') - self.font_layout.addRow(self.vertical_label, self.vertical_combo_box) - self.left_layout.addWidget(self.font_group_box) + self.settings_layout.addRow(self.vertical_label, self.vertical_combo_box) + self.left_layout.addWidget(self.settings_group_box) self.left_layout.addStretch() self.preview_group_box = QtWidgets.QGroupBox(self.right_column) self.preview_group_box.setObjectName('preview_group_box') @@ -92,16 +113,22 @@ class AlertsTab(SettingsTab): self.font_combo_box.activated.connect(self.on_font_combo_box_clicked) self.timeout_spin_box.valueChanged.connect(self.on_timeout_spin_box_changed) self.font_size_spin_box.valueChanged.connect(self.on_font_size_spin_box_changed) + self.repeat_spin_box.valueChanged.connect(self.on_repeat_spin_box_changed) + self.scroll_check_box.toggled.connect(self.scroll_check_box_toggled) def retranslate_ui(self): - self.font_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Font')) + self.font_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Font Settings')) self.font_label.setText(translate('AlertsPlugin.AlertsTab', 'Font name:')) self.font_color_label.setText(translate('AlertsPlugin.AlertsTab', 'Font color:')) self.background_color_label.setText(UiStrings().BackgroundColorColon) self.font_size_label.setText(translate('AlertsPlugin.AlertsTab', 'Font size:')) self.font_size_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().FontSizePtUnit)) + self.background_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Background Settings')) + self.settings_group_box.setTitle(translate('AlertsPlugin.AlertsTab', 'Other Settings')) self.timeout_label.setText(translate('AlertsPlugin.AlertsTab', 'Alert timeout:')) self.timeout_spin_box.setSuffix(' {unit}'.format(unit=UiStrings().Seconds)) + self.repeat_label.setText(translate('AlertsPlugin.AlertsTab', 'Repeat (no. of times):')) + self.scroll_check_box.setText(translate('AlertsPlugin.AlertsTab', 'Enable Scrolling')) self.preview_group_box.setTitle(UiStrings().Preview) self.font_preview.setText(UiStrings().OpenLP) @@ -140,6 +167,24 @@ class AlertsTab(SettingsTab): self.font_size = self.font_size_spin_box.value() self.update_display() + def on_repeat_spin_box_changed(self): + """ + The repeat spin box has changed + """ + self.repeat = self.repeat_spin_box.value() + self.changed = True + + def scroll_check_box_toggled(self): + """ + The scrolling checkbox has been toggled + """ + if self.scroll_check_box.isChecked(): + self.repeat_spin_box.setEnabled(True) + else: + self.repeat_spin_box.setEnabled(False) + self.scroll = self.scroll_check_box.isChecked() + self.changed = True + def load(self): """ Load the settings into the UI. @@ -152,12 +197,16 @@ class AlertsTab(SettingsTab): self.background_color = settings.value('background color') self.font_face = settings.value('font face') self.location = settings.value('location') + self.repeat = settings.value('repeat') + self.scroll = settings.value('scroll') settings.endGroup() self.font_size_spin_box.setValue(self.font_size) self.timeout_spin_box.setValue(self.timeout) self.font_color_button.color = self.font_color self.background_color_button.color = self.background_color + self.repeat_spin_box.setValue(self.repeat) self.vertical_combo_box.setCurrentIndex(self.location) + self.scroll_check_box.setChecked(self.scroll) font = QtGui.QFont() font.setFamily(self.font_face) self.font_combo_box.setCurrentFont(font) @@ -181,6 +230,8 @@ class AlertsTab(SettingsTab): settings.setValue('timeout', self.timeout) self.location = self.vertical_combo_box.currentIndex() settings.setValue('location', self.location) + settings.setValue('repeat', self.repeat) + settings.setValue('scroll', self.scroll_check_box.isChecked()) settings.endGroup() if self.changed: self.settings_form.register_post_process('update_display_css') diff --git a/tests/js/test_display.js b/tests/js/test_display.js index 55da7031a..733b8fd4e 100644 --- a/tests/js/test_display.js +++ b/tests/js/test_display.js @@ -166,7 +166,8 @@ describe("Display.alert", function () { alertBackground.appendChild(alert); settings = '{ \ "location": 1, "font_face": "Segoe UI, Tahoma, Geneva, Verdana, sans-serif", \ - "font_size": 40, "font_color": "#ffffff", "background_color": "#660000" \ + "font_size": 40, "font_color": "#ffffff", "background_color": "#660000", \ + "timeout": 5, "repeat": 1, "scrolling_text": true \ }'; }); @@ -203,7 +204,8 @@ describe("Display.doEntranceTransition", function () { }'; settings = { "location": 2, "font_face": "Tahoma", "font_size": 40, - "font_color": "rgb(255, 255, 255)", "background_color": "rgb(102, 0, 0)" + "font_color": "rgb(255, 255, 255)", "background_color": "rgb(102, 0, 0)", + "timeout": 5, "repeat": 1, "scrolling_text": true }; style.innerHTML = css; document.head.appendChild(style); @@ -305,7 +307,8 @@ describe("Display.getNextAlert", function () { it("should call the alert function correctly if there is an alert in the queue", function () { var settings = { "location": 2, "font_face": "Tahoma", "font_size": 40, - "font_color": "rgb(255, 255, 255)", "background_color": "rgb(102, 0, 0)" + "font_color": "rgb(255, 255, 255)", "background_color": "rgb(102, 0, 0)", + "timeout": 5, "repeat": 1, "scrolling_text": true }; var alertObject = {text: "Queued Alert", settings: settings}; Display._alerts.push(JSON.stringify(alertObject)); @@ -317,6 +320,20 @@ describe("Display.getNextAlert", function () { }); }); +describe("Display.transitionEnd", function () { + beforeEach(function () { + document.body.innerHTML = ""; + alertBackground = document.createElement("div"); + alertBackground.setAttribute("id", "alert-background"); + alertBackground.setAttribute("class", "normal"); + document.body.appendChild(alertBackground); + alertText = document.createElement("p"); + alertText.setAttribute("id","alert"); + alertBackground.appendChild(alertText); + }); + // it("should") +}); + describe("Display.addTextSlide", function () { beforeEach(function() { document.body.innerHTML = "";