diff options
Diffstat (limited to 'browser/components/shell/content')
-rw-r--r-- | browser/components/shell/content/setDesktopBackground.js | 252 | ||||
-rw-r--r-- | browser/components/shell/content/setDesktopBackground.xhtml | 88 |
2 files changed, 340 insertions, 0 deletions
diff --git a/browser/components/shell/content/setDesktopBackground.js b/browser/components/shell/content/setDesktopBackground.js new file mode 100644 index 0000000000..082a1c38e0 --- /dev/null +++ b/browser/components/shell/content/setDesktopBackground.js @@ -0,0 +1,252 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* import-globals-from /browser/base/content/utilityOverlay.js */ + +var gSetBackground = { + _position: AppConstants.platform == "macosx" ? "STRETCH" : "", + _backgroundColor: AppConstants.platform != "macosx" ? 0 : undefined, + _screenWidth: 0, + _screenHeight: 0, + _image: null, + _canvas: null, + _imageName: null, + + get _shell() { + return Cc["@mozilla.org/browser/shell-service;1"].getService( + Ci.nsIShellService + ); + }, + + load() { + this._canvas = document.getElementById("screen"); + this._screenWidth = screen.width; + this._screenHeight = screen.height; + // Cap ratio to 4 so the dialog width doesn't get ridiculous. Highest + // regular screens seem to be 32:9 (3.56) according to Wikipedia. + let screenRatio = Math.min(this._screenWidth / this._screenHeight, 4); + this._canvas.width = this._canvas.height * screenRatio; + document.getElementById("preview-unavailable").style.width = + this._canvas.width + "px"; + + if (AppConstants.platform == "macosx") { + document + .getElementById("SetDesktopBackgroundDialog") + .getButton("accept").hidden = true; + } else { + let multiMonitors = false; + if (AppConstants.platform == "linux") { + // getMonitors only ever returns the primary monitor on Linux, so just + // always show the option + multiMonitors = true; + } else { + const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + const monitors = gfxInfo.getMonitors(); + multiMonitors = monitors.length > 1; + } + + if ( + !multiMonitors || + AppConstants.isPlatformAndVersionAtMost("win", 6.1) + ) { + // Hide span option if < Win8 since that's when it was introduced. + document.getElementById("spanPosition").hidden = true; + } + } + + document.addEventListener("dialogaccept", function() { + gSetBackground.setDesktopBackground(); + }); + // make sure that the correct dimensions will be used + setTimeout( + function(self) { + self.init(window.arguments[0], window.arguments[1]); + }, + 0, + this + ); + }, + + init(aImage, aImageName) { + this._image = aImage; + this._imageName = aImageName; + + // set the size of the coordinate space + this._canvas.width = this._canvas.clientWidth; + this._canvas.height = this._canvas.clientHeight; + + var ctx = this._canvas.getContext("2d"); + ctx.scale( + this._canvas.clientWidth / this._screenWidth, + this._canvas.clientHeight / this._screenHeight + ); + + if (AppConstants.platform != "macosx") { + this._initColor(); + } else { + // Make sure to reset the button state in case the user has already + // set an image as their desktop background. + var setDesktopBackground = document.getElementById( + "setDesktopBackground" + ); + setDesktopBackground.hidden = false; + var bundle = document.getElementById("backgroundBundle"); + setDesktopBackground.label = bundle.getString("DesktopBackgroundSet"); + setDesktopBackground.disabled = false; + + document.getElementById("showDesktopPreferences").hidden = true; + } + this.updatePosition(); + }, + + setDesktopBackground() { + if (AppConstants.platform != "macosx") { + Services.xulStore.persist( + document.getElementById("menuPosition"), + "value" + ); + this._shell.desktopBackgroundColor = this._hexStringToLong( + this._backgroundColor + ); + } else { + Services.obs.addObserver(this, "shell:desktop-background-changed"); + + var bundle = document.getElementById("backgroundBundle"); + var setDesktopBackground = document.getElementById( + "setDesktopBackground" + ); + setDesktopBackground.disabled = true; + setDesktopBackground.label = bundle.getString( + "DesktopBackgroundDownloading" + ); + } + this._shell.setDesktopBackground( + this._image, + Ci.nsIShellService["BACKGROUND_" + this._position], + this._imageName + ); + }, + + updatePosition() { + var ctx = this._canvas.getContext("2d"); + ctx.clearRect(0, 0, this._screenWidth, this._screenHeight); + document.getElementById("preview-unavailable").hidden = true; + + if (AppConstants.platform != "macosx") { + this._position = document.getElementById("menuPosition").value; + } + + switch (this._position) { + case "TILE": + ctx.save(); + ctx.fillStyle = ctx.createPattern(this._image, "repeat"); + ctx.fillRect(0, 0, this._screenWidth, this._screenHeight); + ctx.restore(); + break; + case "STRETCH": + ctx.drawImage(this._image, 0, 0, this._screenWidth, this._screenHeight); + break; + case "CENTER": { + let x = (this._screenWidth - this._image.naturalWidth) / 2; + let y = (this._screenHeight - this._image.naturalHeight) / 2; + ctx.drawImage(this._image, x, y); + break; + } + case "FILL": { + // Try maxing width first, overflow height. + let widthRatio = this._screenWidth / this._image.naturalWidth; + let width = this._image.naturalWidth * widthRatio; + let height = this._image.naturalHeight * widthRatio; + if (height < this._screenHeight) { + // Height less than screen, max height and overflow width. + let heightRatio = this._screenHeight / this._image.naturalHeight; + width = this._image.naturalWidth * heightRatio; + height = this._image.naturalHeight * heightRatio; + } + let x = (this._screenWidth - width) / 2; + let y = (this._screenHeight - height) / 2; + ctx.drawImage(this._image, x, y, width, height); + break; + } + case "FIT": { + // Try maxing width first, top and bottom borders. + let widthRatio = this._screenWidth / this._image.naturalWidth; + let width = this._image.naturalWidth * widthRatio; + let height = this._image.naturalHeight * widthRatio; + let x = 0; + let y = (this._screenHeight - height) / 2; + if (height > this._screenHeight) { + // Height overflow, maximise height, side borders. + let heightRatio = this._screenHeight / this._image.naturalHeight; + width = this._image.naturalWidth * heightRatio; + height = this._image.naturalHeight * heightRatio; + x = (this._screenWidth - width) / 2; + y = 0; + } + ctx.drawImage(this._image, x, y, width, height); + break; + } + case "SPAN": { + document.getElementById("preview-unavailable").hidden = false; + ctx.fillStyle = "#222"; + ctx.fillRect(0, 0, this._screenWidth, this._screenHeight); + ctx.stroke(); + } + } + }, +}; + +if (AppConstants.platform != "macosx") { + gSetBackground._initColor = function() { + var color = this._shell.desktopBackgroundColor; + + const rMask = 4294901760; + const gMask = 65280; + const bMask = 255; + var r = (color & rMask) >> 16; + var g = (color & gMask) >> 8; + var b = color & bMask; + this.updateColor(this._rgbToHex(r, g, b)); + + var colorpicker = document.getElementById("desktopColor"); + colorpicker.value = this._backgroundColor; + }; + + gSetBackground.updateColor = function(aColor) { + this._backgroundColor = aColor; + this._canvas.style.backgroundColor = aColor; + }; + + // Converts a color string in the format "#RRGGBB" to an integer. + gSetBackground._hexStringToLong = function(aString) { + return ( + (parseInt(aString.substring(1, 3), 16) << 16) | + (parseInt(aString.substring(3, 5), 16) << 8) | + parseInt(aString.substring(5, 7), 16) + ); + }; + + gSetBackground._rgbToHex = function(aR, aG, aB) { + return ( + "#" + + [aR, aG, aB] + .map(aInt => aInt.toString(16).replace(/^(.)$/, "0$1")) + .join("") + .toUpperCase() + ); + }; +} else { + gSetBackground.observe = function(aSubject, aTopic, aData) { + if (aTopic == "shell:desktop-background-changed") { + document.getElementById("setDesktopBackground").hidden = true; + document.getElementById("showDesktopPreferences").hidden = false; + + Services.obs.removeObserver(this, "shell:desktop-background-changed"); + } + }; + + gSetBackground.showDesktopPrefs = function() { + this._shell.QueryInterface(Ci.nsIMacShellService).showDesktopPreferences(); + }; +} diff --git a/browser/components/shell/content/setDesktopBackground.xhtml b/browser/components/shell/content/setDesktopBackground.xhtml new file mode 100644 index 0000000000..95b05ec277 --- /dev/null +++ b/browser/components/shell/content/setDesktopBackground.xhtml @@ -0,0 +1,88 @@ +<?xml version="1.0"?> <!-- -*- Mode: HTML -*- --> + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> +<?xml-stylesheet href="chrome://browser/skin/setDesktopBackground.css" type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + windowtype="Shell:SetDesktopBackground" + onload="gSetBackground.load();" + data-l10n-id="set-desktop-background-window" + style="min-width: 30em;"> + +<linkset> + <html:link rel="localization" href="browser/setDesktopBackground.ftl"/> +</linkset> + +<dialog id="SetDesktopBackgroundDialog" +#ifndef XP_MACOSX + buttons="accept,cancel" +#else + buttons="accept" +#endif + buttonidaccept="set-desktop-background-accept"> + +#ifdef XP_MACOSX +#include ../../../base/content/macWindow.inc.xhtml +#else + <script src="chrome://browser/content/utilityOverlay.js"/> +#endif + + <stringbundle id="backgroundBundle" + src="chrome://browser/locale/shellservice.properties"/> + <script src="chrome://browser/content/setDesktopBackground.js"/> + <script src="chrome://global/content/contentAreaUtils.js"/> + +#ifndef XP_MACOSX + <hbox align="center"> + <label data-l10n-id="set-background-position"/> + <menulist id="menuPosition" + oncommand="gSetBackground.updatePosition();" native="true"> + <menupopup> + <menuitem data-l10n-id="set-background-center" value="CENTER"/> + <menuitem data-l10n-id="set-background-tile" value="TILE"/> + <menuitem data-l10n-id="set-background-stretch" value="STRETCH"/> + <menuitem data-l10n-id="set-background-fill" value="FILL"/> + <menuitem data-l10n-id="set-background-fit" value="FIT"/> + <menuitem data-l10n-id="set-background-span" value="SPAN" id="spanPosition"/> + </menupopup> + </menulist> + <spacer flex="1"/> + <label data-l10n-id="set-background-color"/> + <html:input id="desktopColor" + type="color" + onchange="gSetBackground.updateColor(this.value);"/> + </hbox> +#endif + + <vbox align="center"> + <!-- default to 16:9, will be adjusted to match user's actual screen --> + <stack> + <html:canvas id="screen" width="202" height="114" role="presentation"/> + <vbox pack="center"> + <html:p id="preview-unavailable" hidden="" data-l10n-id="set-background-preview-unavailable"></html:p> + </vbox> + </stack> + <image id="monitor-base"/> + </vbox> + +#ifdef XP_MACOSX + <separator/> + + <hbox pack="end"> + <button id="setDesktopBackground" + data-l10n-id="set-desktop-background-accept" + oncommand="gSetBackground.setDesktopBackground();"/> + <button id="showDesktopPreferences" + data-l10n-id="open-desktop-prefs" + oncommand="gSetBackground.showDesktopPrefs();" + hidden="true"/> + </hbox> +#endif + +</dialog> +</window> |