diff --git a/Quelea/languages/gb.lang b/Quelea/languages/gb.lang index 3f5a59ccb..4a7fd59f4 100644 --- a/Quelea/languages/gb.lang +++ b/Quelea/languages/gb.lang @@ -716,4 +716,8 @@ filefilters.description.sunday.plus=Sunday plus songs song.list=Song list password.empty.label=Empty password found password.empty.message=The server password cannot be empty. The default password "quelea" will be used unless you enter something in the password box. +projector.margin.top=Margin Top +projector.margin.right=Margin Right +projector.margin.bottom=Margin Bottom +projector.margin.left=Margin Left slide.transition.label=Use fade transition between slides diff --git a/Quelea/src/main/java/org/quelea/services/utils/PercentMargins.java b/Quelea/src/main/java/org/quelea/services/utils/PercentMargins.java new file mode 100644 index 000000000..e9bef5d68 --- /dev/null +++ b/Quelea/src/main/java/org/quelea/services/utils/PercentMargins.java @@ -0,0 +1,77 @@ +/* + * This file is part of Quelea, free projection software for churches. + * + * Copyright (C) 2012 Michael Berry + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.quelea.services.utils; + +import javafx.geometry.BoundingBox; +import javafx.geometry.Bounds; + +/** + * Percentage-based (0-1) margins to be applied to a display + *

+ * @author Dallon Feldner + */ +public class PercentMargins { + + private double top; + private double right; + private double bottom; + private double left; + + public PercentMargins(double top, double right, double bottom, double left) { + this.top = top; + this.right = right; + this.bottom = bottom; + this.left = left; + } + + @Override + public String toString() { + return top + "," + right + "," + bottom + "," + left; + } + + public double getTop() { + return top; + } + + public double getRight() { + return right; + } + + public double getBottom() { + return bottom; + } + + public double getLeft() { + return left; + } + + public Bounds applyMargins(Bounds coords) { + double leftMargin = left * coords.getWidth(); + double topMargin = top * coords.getHeight(); + + return new BoundingBox( + coords.getMinX() + leftMargin, + coords.getMinY() + topMargin, + coords.getWidth() - leftMargin - right* coords.getWidth(), + coords.getHeight() - topMargin - bottom* coords.getHeight() + ); + } + +} + diff --git a/Quelea/src/main/java/org/quelea/services/utils/QueleaProperties.java b/Quelea/src/main/java/org/quelea/services/utils/QueleaProperties.java index 98ef4190f..7a3b8959a 100644 --- a/Quelea/src/main/java/org/quelea/services/utils/QueleaProperties.java +++ b/Quelea/src/main/java/org/quelea/services/utils/QueleaProperties.java @@ -26,6 +26,7 @@ import java.util.Properties; import java.util.logging.Level; +import com.sun.istack.NotNull; import javafx.geometry.BoundingBox; import javafx.geometry.Bounds; import javafx.scene.paint.Color; @@ -1124,6 +1125,10 @@ public Bounds getProjectorCoords() { Integer.parseInt(prop[3])); } + public Bounds getProjectorCoordsWithMargins() { + return applyProjectorMargin(getProjectorCoords()); + } + /** * Set the custom projector co-ordinates. *

@@ -2274,6 +2279,57 @@ public double getLyricHeightBounds() { return Double.parseDouble(getProperty(lyricHeightBoundKey, "0.9")); } + public PercentMargins getProjectorMargin() { + String[] parts = getProperty(projectorMarginKey, "0,0,0,0").split(","); + if (parts.length == 4) { + return new PercentMargins( + Double.parseDouble(parts[0]), + Double.parseDouble(parts[1]), + Double.parseDouble(parts[2]), + Double.parseDouble(parts[3]) + ); + } else { + return new PercentMargins(0,0,0,0); + } + } + + public void setProjectorMargin(@NotNull PercentMargins margins) { + setProperty(projectorMarginKey, margins.toString()); + } + + public void setProjectorMarginTop(double value) { + PercentMargins prop = getProjectorMargin(); + PercentMargins newProp = new PercentMargins(value, prop.getRight(), prop.getBottom(), prop.getLeft()); + setProjectorMargin(newProp); + } + + public void setProjectorMarginRight(double value) { + PercentMargins prop = getProjectorMargin(); + PercentMargins newProp = new PercentMargins(prop.getTop(), value, prop.getBottom(), prop.getLeft()); + setProjectorMargin(newProp); + } + + public void setProjectorMarginBottom(double value) { + PercentMargins prop = getProjectorMargin(); + PercentMargins newProp = new PercentMargins(prop.getTop(), prop.getRight(), value, prop.getLeft()); + setProjectorMargin(newProp); + } + + public void setProjectorMarginLeft(double value) { + PercentMargins prop = getProjectorMargin(); + PercentMargins newProp = new PercentMargins(prop.getTop(), prop.getRight(), prop.getBottom(), value); + setProjectorMargin(newProp); + } + + public boolean hasProjectorMargin() { + PercentMargins margins = getProjectorMargin(); + return margins.getTop() > 0 || margins.getLeft() > 0 || margins.getBottom() > 0 || margins.getRight() > 0; + } + + public Bounds applyProjectorMargin(Bounds coords) { + return getProjectorMargin().applyMargins(coords); + } + public boolean getDefaultSongDBUpdate() { return Boolean.parseBoolean(getProperty(defaultSongDbUpdateKey, "true")); } diff --git a/Quelea/src/main/java/org/quelea/services/utils/QueleaPropertyKeys.java b/Quelea/src/main/java/org/quelea/services/utils/QueleaPropertyKeys.java index ecdc11d1d..d014e1911 100644 --- a/Quelea/src/main/java/org/quelea/services/utils/QueleaPropertyKeys.java +++ b/Quelea/src/main/java/org/quelea/services/utils/QueleaPropertyKeys.java @@ -126,6 +126,11 @@ public class QueleaPropertyKeys { public static final String stageWCoordKey = "stage.width.coord"; public static final String stageHCoordKey = "stage.height.coord"; public static final String darkThemeKey = "use.dark.theme"; + public static final String projectorMarginKey = "projector.margin"; + public static final String projectorMarginTopKey = "projector.margin.top"; + public static final String projectorMarginRightKey = "projector.margin.right"; + public static final String projectorMarginBottomKey = "projector.margin.bottom"; + public static final String projectorMarginLeftKey = "projector.margin.left"; public static final String useSlideTransitionKey = "use.fade"; public static final String slideTransitionInDurationKey = "slide.transition.duration.in"; public static final String slideTransitionOutDurationKey = "slide.transition.duration.out"; diff --git a/Quelea/src/main/java/org/quelea/windows/main/Main.java b/Quelea/src/main/java/org/quelea/windows/main/Main.java index dafe8dc84..514abbede 100644 --- a/Quelea/src/main/java/org/quelea/windows/main/Main.java +++ b/Quelea/src/main/java/org/quelea/windows/main/Main.java @@ -184,19 +184,31 @@ public void run() { if (lyricsHidden) { LOGGER.log(Level.INFO, "Hiding projector display on monitor 0 (base 0!)"); Platform.runLater(() -> { - fullScreenWindow = new DisplayStage(Utils.getBoundsFromRect2D(monitors.get(0).getVisualBounds()), false); + fullScreenWindow = new DisplayStage( + QueleaProperties.get().applyProjectorMargin( + Utils.getBoundsFromRect2D(monitors.get(0).getVisualBounds()) + ), + false + ); fullScreenWindow.hide(); }); } else if (QueleaProperties.get().isProjectorModeCoords()) { - LOGGER.log(Level.INFO, "Starting projector display: ", QueleaProperties.get().getProjectorCoords()); + LOGGER.log(Level.INFO, "Starting projector display: ", QueleaProperties.get().getProjectorCoordsWithMargins()); Platform.runLater(() -> { - fullScreenWindow = new DisplayStage(QueleaProperties.get().getProjectorCoords(), false); + fullScreenWindow = new DisplayStage(QueleaProperties.get().getProjectorCoordsWithMargins(), false); }); } else { LOGGER.log(Level.INFO, "Starting projector display on monitor {0} (base 0!)", projectorScreen); Platform.runLater(() -> { - fullScreenWindow = new DisplayStage(Utils.getBoundsFromRect2D(monitors.get(projectorScreen).getBounds()), false); - fullScreenWindow.setFullScreenAlwaysOnTop(true); + fullScreenWindow = new DisplayStage( + QueleaProperties.get().applyProjectorMargin( + Utils.getBoundsFromRect2D(monitors.get(projectorScreen).getBounds()) + ), + false + ); + if (!QueleaProperties.get().hasProjectorMargin()) { + fullScreenWindow.setFullScreenAlwaysOnTop(true); + } }); } diff --git a/Quelea/src/main/java/org/quelea/windows/options/DisplayGroup.java b/Quelea/src/main/java/org/quelea/windows/options/DisplayGroup.java index 5ac7a08b6..284a74796 100644 --- a/Quelea/src/main/java/org/quelea/windows/options/DisplayGroup.java +++ b/Quelea/src/main/java/org/quelea/windows/options/DisplayGroup.java @@ -17,6 +17,7 @@ */ package org.quelea.windows.options; +import com.dlsc.formsfx.model.structure.DoubleField; import com.dlsc.formsfx.model.structure.Field; import com.dlsc.formsfx.model.structure.IntegerField; import com.dlsc.preferencesfx.formsfx.view.controls.SimpleComboBoxControl; @@ -24,6 +25,7 @@ import com.dlsc.preferencesfx.model.Group; import com.dlsc.preferencesfx.model.Setting; import javafx.beans.property.*; +import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; @@ -31,8 +33,11 @@ import javafx.geometry.Bounds; import javafx.stage.Screen; import org.quelea.services.languages.LabelGrabber; +import org.quelea.services.utils.PercentMargins; import org.quelea.services.utils.QueleaProperties; +import org.quelea.windows.options.customprefs.PercentSliderControl; +import java.util.ArrayList; import java.util.HashMap; import static org.quelea.services.utils.QueleaPropertyKeys.*; @@ -41,18 +46,20 @@ public class DisplayGroup { private boolean displayChange = false; private Group group; - DisplayGroup(String groupName, boolean custom, HashMap bindings) { - BooleanProperty useCustomPosition = new SimpleBooleanProperty(false); - if (groupName.equals(LabelGrabber.INSTANCE.getLabel("projector.screen.label"))) { - useCustomPosition = new SimpleBooleanProperty(QueleaProperties.get().isProjectorModeCoords()); - } else if (groupName.equals(LabelGrabber.INSTANCE.getLabel("stage.screen.label"))) { - useCustomPosition = new SimpleBooleanProperty(QueleaProperties.get().isStageModeCoords()); - } - useCustomPosition.addListener(e -> { - displayChange = true; - }); + DisplayGroup(String groupName, HashMap bindings) { + + boolean isControl = groupName.equals(LabelGrabber.INSTANCE.getLabel(("control.screen.label"))); + boolean isProjector = groupName.equals(LabelGrabber.INSTANCE.getLabel(("projector.screen.label"))); + boolean isStage = groupName.equals(LabelGrabber.INSTANCE.getLabel("stage.screen.label")); - ObservableList availableScreens = getAvailableScreens(custom); + // can be disabled? + boolean noScreen = isProjector || isStage; + // Support a custom position? + boolean useCustom = isProjector || isStage; + // Support display margins? + boolean useMargins = isProjector; + + ObservableList availableScreens = getAvailableScreens(useCustom); ListProperty screenListProperty = new SimpleListProperty<>(availableScreens); ObjectProperty screenSelectProperty = new SimpleObjectProperty<>(availableScreens.get(0)); Field customControl = Field.ofSingleSelectionType(screenListProperty, screenSelectProperty).render( @@ -66,80 +73,188 @@ public class DisplayGroup { displayChange = true; }); - if (!custom) { - int screen = QueleaProperties.get().getControlScreen(); + ArrayList settings = new ArrayList<>(); + + int screen; + String screenKey; + if (isControl) + { + screen = QueleaProperties.get().getControlScreen(); + screenKey = controlScreenKey; + } else if (isProjector) { + screen = QueleaProperties.get().getProjectorScreen(); + screenKey = projectorScreenKey; + } else if (isStage) { + screen = QueleaProperties.get().getStageScreen(); + screenKey = stageScreenKey; + } else { + throw new IllegalArgumentException("Unsupported groupName: " + groupName); + } + + if (noScreen) { + screen++; // Compensate for "none" value in available screens + screenSelectProperty.setValue(screen > 0 && screen < availableScreens.size() ? availableScreens.get(screen) : availableScreens.get(0)); + } else { screenSelectProperty.setValue(screen > -1 ? availableScreens.get(screen) : availableScreens.get(0)); - group = Group.of(groupName, - Setting.of(groupName, customControl, screenSelectProperty).customKey(controlScreenKey) - ); + } + + settings.add(Setting.of(groupName, customControl, screenSelectProperty).customKey(screenKey)); + + if (useCustom) { + setupCustomPosition(bindings, isProjector, isStage, customControl, settings); + } + + if (useMargins) { + setupMargins(isProjector, settings); + } + + + Setting[] settingsArray = new Setting[settings.size()]; + group = Group.of(groupName, + settings.toArray(settingsArray) + ); + } + + private void setupCustomPosition( HashMap bindings, boolean isProjector, boolean isStage, Field customControl, ArrayList settings) { + Bounds bounds; + BooleanProperty useCustomPosition; + if (isProjector) { + bounds = QueleaProperties.get().getProjectorCoords(); + useCustomPosition = new SimpleBooleanProperty(QueleaProperties.get().isProjectorModeCoords()); + } else if (isStage) { + bounds = QueleaProperties.get().getStageCoords(); + useCustomPosition = new SimpleBooleanProperty(QueleaProperties.get().isStageModeCoords()); } else { - int screen; - Bounds bounds; - if (groupName.equals(LabelGrabber.INSTANCE.getLabel("projector.screen.label"))) { - screen = QueleaProperties.get().getProjectorScreen(); - bounds = QueleaProperties.get().getProjectorCoords(); + throw new IllegalArgumentException("Unsupported groupName - is neither projector nor stage"); + } + + + IntegerProperty widthProperty = new SimpleIntegerProperty((int) bounds.getWidth()); + IntegerProperty heightProperty = new SimpleIntegerProperty((int) bounds.getHeight()); + IntegerProperty xProperty = new SimpleIntegerProperty((int) bounds.getMinX()); + IntegerProperty yProperty = new SimpleIntegerProperty((int) bounds.getMinY()); + IntegerField sizeWith = Field.ofIntegerType(widthProperty).render( + new SimpleIntegerControl()); + IntegerField sizeHeight = Field.ofIntegerType(heightProperty).render( + new SimpleIntegerControl()); + IntegerField posX = Field.ofIntegerType(xProperty).render( + new SimpleIntegerControl()); + IntegerField posY = Field.ofIntegerType(yProperty).render( + new SimpleIntegerControl()); + + widthProperty.addListener(e -> { + displayChange = true; + }); + + heightProperty.addListener(e -> { + displayChange = true; + }); + + xProperty.addListener(e -> { + displayChange = true; + }); + + yProperty.addListener(e -> { + displayChange = true; + }); + + useCustomPosition.addListener(e -> { + displayChange = true; + }); + + + settings.add(Setting.of(LabelGrabber.INSTANCE.getLabel("custom.position.text"), useCustomPosition) + .customKey(isProjector ? projectorModeKey : stageModeKey)); + settings.add(Setting.of("W", sizeWith, widthProperty) + .customKey(isProjector ? projectorWCoordKey : stageWCoordKey)); + settings.add(Setting.of("H", sizeHeight, heightProperty) + .customKey(isProjector ? projectorHCoordKey : stageHCoordKey)); + settings.add(Setting.of("X", posX, xProperty) + .customKey(isProjector ? projectorXCoordKey : stageXCoordKey)); + settings.add(Setting.of("Y", posY, yProperty) + .customKey(isProjector ? projectorYCoordKey : stageYCoordKey)); + + bindings.put(sizeWith, useCustomPosition.not()); + bindings.put(sizeHeight, useCustomPosition.not()); + bindings.put(posX, useCustomPosition.not()); + bindings.put(posY, useCustomPosition.not()); + bindings.put(customControl, useCustomPosition); + } + + private void setupMargins(boolean isProjector, ArrayList settings) { + PercentMargins margins; + if (isProjector) { + margins = QueleaProperties.get().getProjectorMargin(); + } else { + throw new IllegalArgumentException("Unsupported groupName (isn't projector)"); + } + + DoubleProperty marginTopProperty = new SimpleDoubleProperty(margins.getTop()); + DoubleProperty marginRightProperty = new SimpleDoubleProperty(margins.getRight()); + DoubleProperty marginBottomProperty = new SimpleDoubleProperty(margins.getBottom()); + DoubleProperty marginLeftProperty = new SimpleDoubleProperty(margins.getLeft()); + + DoubleField marginTopField = Field.ofDoubleType(marginTopProperty).render( + new PercentSliderControl(0.0, 0.99, 2)); + DoubleField marginRightField = Field.ofDoubleType(marginRightProperty).render( + new PercentSliderControl(0.0, 0.99, 2)); + DoubleField marginBottomField = Field.ofDoubleType(marginBottomProperty).render( + new PercentSliderControl(0.0, 0.99, 2)); + DoubleField marginLeftField = Field.ofDoubleType(marginLeftProperty).render( + new PercentSliderControl(0.0, 0.99, 2)); + + ChangeListener onMarginNumberChange = (observable, oldValue, newValue) -> { + DoubleProperty property; + DoubleProperty opposite; + if (observable == marginTopProperty) { + property = marginTopProperty; + opposite = marginBottomProperty; + } else if (observable == marginRightProperty) { + property = marginRightProperty; + opposite = marginLeftProperty; + } else if (observable == marginBottomProperty) { + property = marginBottomProperty; + opposite = marginTopProperty; + } else if (observable == marginLeftProperty) { + property = marginLeftProperty; + opposite = marginRightProperty; } else { - screen = QueleaProperties.get().getStageScreen(); - bounds = QueleaProperties.get().getStageCoords(); + throw new IllegalArgumentException(); + } + + displayChange = true; + + // make sure the margins only add up to 99 at most, leaving 1% for content + double total = property.getValue() + opposite.getValue(); + if (total > 0.99) { + double suggestedOpposite = 0.99 - property.getValue(); + if (suggestedOpposite > 0) { + opposite.set(suggestedOpposite); + } else { + // A number greater than 99 has been selected + // clamp to 99 + property.set(0.99); + opposite.set(0); + } } + }; - IntegerProperty widthProperty = new SimpleIntegerProperty((int) bounds.getWidth()); - IntegerProperty heightProperty = new SimpleIntegerProperty((int) bounds.getHeight()); - IntegerProperty xProperty = new SimpleIntegerProperty((int) bounds.getMinX()); - IntegerProperty yProperty = new SimpleIntegerProperty((int) bounds.getMinY()); - IntegerField sizeWith = Field.ofIntegerType(widthProperty).render( - new SimpleIntegerControl()); - IntegerField sizeHeight = Field.ofIntegerType(heightProperty).render( - new SimpleIntegerControl()); - IntegerField posX = Field.ofIntegerType(xProperty).render( - new SimpleIntegerControl()); - IntegerField posY = Field.ofIntegerType(yProperty).render( - new SimpleIntegerControl()); - - widthProperty.addListener(e -> { - displayChange = true; - }); - - heightProperty.addListener(e -> { - displayChange = true; - }); - - xProperty.addListener(e -> { - displayChange = true; - }); - - yProperty.addListener(e -> { - displayChange = true; - }); - screen++; // Compensate for "none" value in available screens + marginTopProperty.addListener(onMarginNumberChange); + marginRightProperty.addListener(onMarginNumberChange); + marginBottomProperty.addListener(onMarginNumberChange); + marginLeftProperty.addListener(onMarginNumberChange); - screenSelectProperty.setValue(screen > 0 && screen < availableScreens.size() ? availableScreens.get(screen) : availableScreens.get(0)); - boolean projectorGroup = groupName.equals(LabelGrabber.INSTANCE.getLabel("projector.screen.label")); - - group = Group.of(groupName, - Setting.of(groupName, customControl, screenSelectProperty) - .customKey(projectorGroup ? projectorScreenKey : stageScreenKey), - Setting.of(LabelGrabber.INSTANCE.getLabel("custom.position.text"), useCustomPosition) - .customKey(projectorGroup ? projectorModeKey : stageModeKey), - Setting.of("W", sizeWith, widthProperty) - .customKey(projectorGroup ? projectorWCoordKey : stageWCoordKey), - Setting.of("H", sizeHeight, heightProperty) - .customKey(projectorGroup ? projectorHCoordKey : stageHCoordKey), - Setting.of("X", posX, xProperty) - .customKey(projectorGroup ? projectorXCoordKey : stageXCoordKey), - Setting.of("Y", posY, yProperty) - .customKey(projectorGroup ? projectorYCoordKey : stageYCoordKey) - ); - - bindings.put(sizeWith, useCustomPosition.not()); - bindings.put(sizeHeight, useCustomPosition.not()); - bindings.put(posX, useCustomPosition.not()); - bindings.put(posY, useCustomPosition.not()); - bindings.put(customControl, useCustomPosition); - } - } + settings.add(Setting.of(LabelGrabber.INSTANCE.getLabel("projector.margin.top"), marginTopField, marginTopProperty) + .customKey(projectorMarginTopKey)); + settings.add(Setting.of(LabelGrabber.INSTANCE.getLabel("projector.margin.right"), marginRightField, marginRightProperty) + .customKey(projectorMarginRightKey)); + settings.add(Setting.of(LabelGrabber.INSTANCE.getLabel("projector.margin.bottom"), marginBottomField, marginBottomProperty) + .customKey(projectorMarginBottomKey)); + settings.add(Setting.of(LabelGrabber.INSTANCE.getLabel("projector.margin.left"), marginLeftField, marginLeftProperty) + .customKey(projectorMarginLeftKey)); + } /** * Get a list model describing the available graphical devices. diff --git a/Quelea/src/main/java/org/quelea/windows/options/OptionsDisplaySetupPanel.java b/Quelea/src/main/java/org/quelea/windows/options/OptionsDisplaySetupPanel.java index 1d108e4ca..a54ed15cc 100644 --- a/Quelea/src/main/java/org/quelea/windows/options/OptionsDisplaySetupPanel.java +++ b/Quelea/src/main/java/org/quelea/windows/options/OptionsDisplaySetupPanel.java @@ -46,9 +46,9 @@ public class OptionsDisplaySetupPanel { */ OptionsDisplaySetupPanel(HashMap bindings) { this.bindings = bindings; - controlScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("control.screen.label"), false, bindings); - projectorScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("projector.screen.label"), true, bindings); - stageScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("stage.screen.label"), true, bindings); + controlScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("control.screen.label"), bindings); + projectorScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("projector.screen.label"), bindings); + stageScreen = new DisplayGroup(LabelGrabber.INSTANCE.getLabel("stage.screen.label"), bindings); GraphicsDeviceWatcher.INSTANCE.addGraphicsDeviceListener(devices -> { QueleaApp.get().getMainWindow().getPreferencesDialog().updatePos(); diff --git a/Quelea/src/main/java/org/quelea/windows/options/PreferenceStorageHandler.java b/Quelea/src/main/java/org/quelea/windows/options/PreferenceStorageHandler.java index aa18aea16..a654058b3 100644 --- a/Quelea/src/main/java/org/quelea/windows/options/PreferenceStorageHandler.java +++ b/Quelea/src/main/java/org/quelea/windows/options/PreferenceStorageHandler.java @@ -208,6 +208,18 @@ public void saveObject(String breadcrumb, Object object) { case QueleaPropertyKeys.projectorYCoordKey: QueleaProperties.get().setYProjectorCoord(object.toString()); break; + case QueleaPropertyKeys.projectorMarginTopKey: + QueleaProperties.get().setProjectorMarginTop((Double) object); + break; + case QueleaPropertyKeys.projectorMarginRightKey: + QueleaProperties.get().setProjectorMarginRight((Double) object); + break; + case QueleaPropertyKeys.projectorMarginBottomKey: + QueleaProperties.get().setProjectorMarginBottom((Double) object); + break; + case QueleaPropertyKeys.projectorMarginLeftKey: + QueleaProperties.get().setProjectorMarginLeft((Double) object); + break; case QueleaPropertyKeys.stageHCoordKey: QueleaProperties.get().setHeightStageCoord(object.toString()); break; @@ -336,6 +348,14 @@ public Object loadObject(String breadcrumb, Object defaultObject) { return QueleaProperties.get().getProjectorCoords().getMinX(); case QueleaPropertyKeys.projectorYCoordKey: return QueleaProperties.get().getProjectorCoords().getMinY(); + case QueleaPropertyKeys.projectorMarginTopKey: + return QueleaProperties.get().getProjectorMargin().getTop(); + case QueleaPropertyKeys.projectorMarginRightKey: + return QueleaProperties.get().getProjectorMargin().getRight(); + case QueleaPropertyKeys.projectorMarginBottomKey: + return QueleaProperties.get().getProjectorMargin().getBottom(); + case QueleaPropertyKeys.projectorMarginLeftKey: + return QueleaProperties.get().getProjectorMargin().getLeft(); case QueleaPropertyKeys.stageHCoordKey: return QueleaProperties.get().getStageCoords().getHeight(); case QueleaPropertyKeys.stageWCoordKey: diff --git a/Quelea/src/main/java/org/quelea/windows/options/PreferencesDialog.java b/Quelea/src/main/java/org/quelea/windows/options/PreferencesDialog.java index 33ac4fe72..550ede78d 100644 --- a/Quelea/src/main/java/org/quelea/windows/options/PreferencesDialog.java +++ b/Quelea/src/main/java/org/quelea/windows/options/PreferencesDialog.java @@ -169,11 +169,15 @@ public void updatePos() { int projectorScreen = QueleaProperties.get().getProjectorScreen(); Bounds bounds; if (QueleaProperties.get().isProjectorModeCoords()) { - bounds = QueleaProperties.get().getProjectorCoords(); + bounds = QueleaProperties.get().getProjectorCoordsWithMargins(); } else { - bounds = Utils.getBoundsFromRect2D( - monitors.get(projectorScreen < 0 || projectorScreen >= monitors.size() ? 0 : projectorScreen) - .getBounds()); + bounds = QueleaProperties.get().applyProjectorMargin( + Utils.getBoundsFromRect2D( + monitors + .get(projectorScreen < 0 || projectorScreen >= monitors.size() ? 0 : projectorScreen) + .getBounds() + ) + ); } fiLyricWindow.setAreaImmediate(bounds); if (!QueleaApp.get().getMainWindow().getMainPanel().getLivePanel().getHide().isSelected()) { @@ -186,7 +190,9 @@ public void updatePos() { fiLyricWindow.hide(); VLCWindow.INSTANCE.refreshPosition(); } else { - fiLyricWindow.setFullScreenAlwaysOnTop(true); + if (!QueleaProperties.get().hasProjectorMargin()) { + fiLyricWindow.setFullScreenAlwaysOnTop(true); + } } } else { fiLyricWindow.setFullScreenAlwaysOnTop(false);