OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * Apps v2 custom title bar implementation | 7 * Apps v2 custom title bar implementation |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | 10 'use strict'; |
(...skipping 12 matching lines...) Expand all Loading... |
23 */ | 23 */ |
24 this.clientSession_ = null; | 24 this.clientSession_ = null; |
25 | 25 |
26 /** | 26 /** |
27 * @type {HTMLElement} | 27 * @type {HTMLElement} |
28 * @private | 28 * @private |
29 */ | 29 */ |
30 this.titleBar_ = titleBar; | 30 this.titleBar_ = titleBar; |
31 | 31 |
32 /** | 32 /** |
33 * @type {HTMLElement} | |
34 * @private | |
35 */ | |
36 this.hoverTarget_ = /** @type {HTMLElement} */ | |
37 (titleBar.querySelector('.window-controls-hover-target')); | |
38 base.debug.assert(this.hoverTarget_ != null); | |
39 | |
40 /** | |
41 * @type {remoting.OptionsMenu} | 33 * @type {remoting.OptionsMenu} |
42 * @private | 34 * @private |
43 */ | 35 */ |
44 this.optionsMenu_ = new remoting.OptionsMenu( | 36 this.optionsMenu_ = new remoting.OptionsMenu( |
45 titleBar.querySelector('.menu-send-ctrl-alt-del'), | 37 titleBar.querySelector('.menu-send-ctrl-alt-del'), |
46 titleBar.querySelector('.menu-send-print-screen'), | 38 titleBar.querySelector('.menu-send-print-screen'), |
47 titleBar.querySelector('.menu-resize-to-client'), | 39 titleBar.querySelector('.menu-resize-to-client'), |
48 titleBar.querySelector('.menu-shrink-to-fit'), | 40 titleBar.querySelector('.menu-shrink-to-fit'), |
49 titleBar.querySelector('.menu-new-connection'), | 41 titleBar.querySelector('.menu-new-connection'), |
50 null, | 42 null, |
(...skipping 16 matching lines...) Expand all Loading... |
67 base.debug.assert(this.maximizeRestoreControl_ != null); | 59 base.debug.assert(this.maximizeRestoreControl_ != null); |
68 | 60 |
69 var optionsButton = titleBar.querySelector('.window-options'); | 61 var optionsButton = titleBar.querySelector('.window-options'); |
70 base.debug.assert(optionsButton != null); | 62 base.debug.assert(optionsButton != null); |
71 this.optionMenuButton_ = new remoting.MenuButton( | 63 this.optionMenuButton_ = new remoting.MenuButton( |
72 optionsButton, | 64 optionsButton, |
73 this.onShowOptionsMenu_.bind(this), | 65 this.onShowOptionsMenu_.bind(this), |
74 this.onHideOptionsMenu_.bind(this)); | 66 this.onHideOptionsMenu_.bind(this)); |
75 | 67 |
76 /** | 68 /** |
| 69 * @type {HTMLElement} |
| 70 * @private |
| 71 */ |
| 72 this.optionsMenuList_ = /** @type {HTMLElement} */ |
| 73 (optionsButton.querySelector('.window-options-menu')); |
| 74 base.debug.assert(this.optionsMenu_ != null); |
| 75 |
| 76 /** |
77 * @type {Array.<{cls:string, fn: function()}>} | 77 * @type {Array.<{cls:string, fn: function()}>} |
78 */ | 78 */ |
79 var handlers = [ | 79 var handlers = [ |
80 { cls: 'window-disconnect', fn: this.disconnectSession_.bind(this) }, | 80 { cls: 'window-disconnect', fn: this.disconnectSession_.bind(this) }, |
81 { cls: 'window-maximize-restore', | 81 { cls: 'window-maximize-restore', |
82 fn: this.maximizeOrRestoreWindow_.bind(this) }, | 82 fn: this.maximizeOrRestoreWindow_.bind(this) }, |
83 { cls: 'window-minimize', fn: this.minimizeWindow_.bind(this) }, | 83 { cls: 'window-minimize', fn: this.minimizeWindow_.bind(this) }, |
84 { cls: 'window-close', fn: window.close.bind(window) }, | 84 { cls: 'window-close', fn: window.close.bind(window) }, |
85 { cls: 'window-controls-stub', fn: this.toggleWindowControls_.bind(this) } | 85 { cls: 'window-controls-stub', fn: this.toggleWindowControls_.bind(this) } |
86 ]; | 86 ]; |
87 for (var i = 0; i < handlers.length; ++i) { | 87 for (var i = 0; i < handlers.length; ++i) { |
88 var element = titleBar.querySelector('.' + handlers[i].cls); | 88 var element = titleBar.querySelector('.' + handlers[i].cls); |
89 base.debug.assert(element != null); | 89 base.debug.assert(element != null); |
90 element.addEventListener('click', handlers[i].fn, false); | 90 element.addEventListener('click', handlers[i].fn, false); |
91 } | 91 } |
92 | 92 |
93 // Ensure that tool-tips are always correct. | 93 // Ensure that tool-tips are always correct. |
94 this.updateMaximizeOrRestoreIconTitle_(); | 94 this.handleWindowStateChange_(); |
95 chrome.app.window.current().onMaximized.addListener( | 95 chrome.app.window.current().onMaximized.addListener( |
96 this.updateMaximizeOrRestoreIconTitle_.bind(this)); | 96 this.handleWindowStateChange_.bind(this)); |
97 chrome.app.window.current().onRestored.addListener( | 97 chrome.app.window.current().onRestored.addListener( |
98 this.updateMaximizeOrRestoreIconTitle_.bind(this)); | 98 this.handleWindowStateChange_.bind(this)); |
99 chrome.app.window.current().onFullscreened.addListener( | 99 chrome.app.window.current().onFullscreened.addListener( |
100 this.updateMaximizeOrRestoreIconTitle_.bind(this)); | 100 this.handleWindowStateChange_.bind(this)); |
101 chrome.app.window.current().onFullscreened.addListener( | 101 chrome.app.window.current().onFullscreened.addListener( |
102 this.showWindowControlsPreview_.bind(this)); | 102 this.showWindowControlsPreview_.bind(this)); |
103 }; | 103 }; |
104 | 104 |
105 /** | 105 /** |
106 * @param {remoting.ClientSession} clientSession The client session, or null if | 106 * @param {remoting.ClientSession} clientSession The client session, or null if |
107 * there is no connection. | 107 * there is no connection. |
108 */ | 108 */ |
109 remoting.WindowFrame.prototype.setClientSession = function(clientSession) { | 109 remoting.WindowFrame.prototype.setClientSession = function(clientSession) { |
110 this.optionsMenu_.setClientSession(clientSession); | 110 this.optionsMenu_.setClientSession(clientSession); |
111 this.clientSession_ = clientSession; | 111 this.clientSession_ = clientSession; |
112 var windowTitle = document.head.querySelector('title'); | 112 var windowTitle = document.head.querySelector('title'); |
113 if (this.clientSession_) { | 113 if (this.clientSession_) { |
114 document.body.classList.add('connected'); | 114 document.body.classList.add('connected'); |
115 this.title_.innerText = clientSession.getHostDisplayName(); | 115 this.title_.innerText = clientSession.getHostDisplayName(); |
116 windowTitle.innerText = clientSession.getHostDisplayName() + ' - ' + | 116 windowTitle.innerText = clientSession.getHostDisplayName() + ' - ' + |
117 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME'); | 117 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME'); |
118 } else { | 118 } else { |
119 document.body.classList.remove('connected'); | 119 document.body.classList.remove('connected'); |
120 this.title_.innerHTML = ' '; | 120 this.title_.innerHTML = ' '; |
121 windowTitle.innerText = | 121 windowTitle.innerText = |
122 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME'); | 122 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME'); |
123 } | 123 } |
124 this.updateMaximizeOrRestoreIconTitle_(); | 124 this.handleWindowStateChange_(); |
125 }; | 125 }; |
126 | 126 |
127 /** | 127 /** |
128 * @return {{width: number, height: number}} The size of the window, ignoring | 128 * @return {{width: number, height: number}} The size of the window, ignoring |
129 * the title-bar and window borders, if visible. | 129 * the title-bar and window borders, if visible. |
130 */ | 130 */ |
131 remoting.WindowFrame.prototype.getClientArea = function() { | 131 remoting.WindowFrame.prototype.getClientArea = function() { |
132 if (chrome.app.window.current().isFullscreen()) { | 132 if (chrome.app.window.current().isFullscreen()) { |
133 return { 'height': window.innerHeight, 'width': window.innerWidth }; | 133 return { 'height': window.innerHeight, 'width': window.innerWidth }; |
134 } else { | 134 } else { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 * @private | 180 * @private |
181 */ | 181 */ |
182 remoting.WindowFrame.prototype.minimizeWindow_ = function() { | 182 remoting.WindowFrame.prototype.minimizeWindow_ = function() { |
183 chrome.app.window.current().minimize(); | 183 chrome.app.window.current().minimize(); |
184 }; | 184 }; |
185 | 185 |
186 /** | 186 /** |
187 * @private | 187 * @private |
188 */ | 188 */ |
189 remoting.WindowFrame.prototype.toggleWindowControls_ = function() { | 189 remoting.WindowFrame.prototype.toggleWindowControls_ = function() { |
190 this.hoverTarget_.classList.toggle('opened'); | 190 this.titleBar_.classList.toggle('opened'); |
191 }; | 191 }; |
192 | 192 |
193 /** | 193 /** |
194 * Update the tool-top for the maximize/full-screen/restore icon to reflect | 194 * Update the tool-top for the maximize/full-screen/restore icon to reflect |
195 * its current behaviour. | 195 * its current behaviour. |
196 * | 196 * |
197 * @private | 197 * @private |
198 */ | 198 */ |
199 remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() { | 199 remoting.WindowFrame.prototype.handleWindowStateChange_ = function() { |
| 200 // Set the title for the maximize/restore/full-screen button |
200 /** @type {string} */ | 201 /** @type {string} */ |
201 var tag = ''; | 202 var tag = ''; |
202 if (chrome.app.window.current().isFullscreen()) { | 203 if (chrome.app.window.current().isFullscreen()) { |
203 tag = /*i18n-content*/'EXIT_FULL_SCREEN'; | 204 tag = /*i18n-content*/'EXIT_FULL_SCREEN'; |
204 } else if (chrome.app.window.current().isMaximized()) { | 205 } else if (chrome.app.window.current().isMaximized()) { |
205 tag = /*i18n-content*/'RESTORE_WINDOW'; | 206 tag = /*i18n-content*/'RESTORE_WINDOW'; |
206 } else if (this.clientSession_) { | 207 } else if (this.clientSession_) { |
207 tag = /*i18n-content*/'FULL_SCREEN'; | 208 tag = /*i18n-content*/'FULL_SCREEN'; |
208 } else { | 209 } else { |
209 tag = /*i18n-content*/'MAXIMIZE_WINDOW'; | 210 tag = /*i18n-content*/'MAXIMIZE_WINDOW'; |
210 } | 211 } |
211 this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag); | 212 this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag); |
| 213 |
| 214 // Ensure that the options menu aligns correctly for the side of the window |
| 215 // it occupies. |
| 216 if (chrome.app.window.current().isFullscreen()) { |
| 217 this.optionsMenuList_.classList.add('right-align'); |
| 218 } else { |
| 219 this.optionsMenuList_.classList.remove('right-align'); |
| 220 } |
212 }; | 221 }; |
213 | 222 |
214 /** | 223 /** |
215 * Callback invoked when the options menu is shown. | 224 * Callback invoked when the options menu is shown. |
216 * @private | 225 * @private |
217 */ | 226 */ |
218 remoting.WindowFrame.prototype.onShowOptionsMenu_ = function() { | 227 remoting.WindowFrame.prototype.onShowOptionsMenu_ = function() { |
219 this.optionsMenu_.onShow(); | 228 this.optionsMenu_.onShow(); |
220 this.hoverTarget_.classList.add('menu-opened'); | 229 this.titleBar_.classList.add('menu-opened'); |
221 }; | 230 }; |
222 | 231 |
223 /** | 232 /** |
224 * Callback invoked when the options menu is shown. | 233 * Callback invoked when the options menu is shown. |
225 * @private | 234 * @private |
226 */ | 235 */ |
227 remoting.WindowFrame.prototype.onHideOptionsMenu_ = function() { | 236 remoting.WindowFrame.prototype.onHideOptionsMenu_ = function() { |
228 this.hoverTarget_.classList.remove('menu-opened'); | 237 this.titleBar_.classList.remove('menu-opened'); |
229 }; | 238 }; |
230 | 239 |
231 /** | 240 /** |
232 * Show the window controls for a few seconds | 241 * Show the window controls for a few seconds |
233 * | 242 * |
234 * @private | 243 * @private |
235 */ | 244 */ |
236 remoting.WindowFrame.prototype.showWindowControlsPreview_ = function() { | 245 remoting.WindowFrame.prototype.showWindowControlsPreview_ = function() { |
237 /** | 246 /** |
238 * @type {HTMLElement} | 247 * @type {HTMLElement} |
239 */ | 248 */ |
240 var target = this.hoverTarget_; | 249 var target = this.titleBar_; |
241 var kPreviewTimeoutMs = 3000; | 250 var kPreviewTimeoutMs = 3000; |
242 var hidePreview = function() { | 251 var hidePreview = function() { |
243 target.classList.remove('preview'); | 252 target.classList.remove('preview'); |
244 }; | 253 }; |
245 target.classList.add('preview'); | 254 target.classList.add('preview'); |
246 window.setTimeout(hidePreview, kPreviewTimeoutMs); | 255 window.setTimeout(hidePreview, kPreviewTimeoutMs); |
247 }; | 256 }; |
248 | 257 |
249 | 258 |
250 /** @type {remoting.WindowFrame} */ | 259 /** @type {remoting.WindowFrame} */ |
251 remoting.windowFrame = null; | 260 remoting.windowFrame = null; |
OLD | NEW |