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
3 // found in the LICENSE file.
7 * Apps v2 custom title bar implementation
12 /** @suppress {duplicate} */
13 var remoting
= remoting
|| {};
16 * @param {HTMLElement} titleBar The root node of the title-bar DOM hierarchy.
17 * @param {function()} disconnectCallback Callback for disconnecting the
21 remoting
.WindowFrame = function(titleBar
, disconnectCallback
) {
22 /** @private {remoting.DesktopConnectedView} */
23 this.desktopConnectedView_
= null;
25 /** @private {HTMLElement} */
26 this.titleBar_
= titleBar
;
28 /** @private {HTMLElement} */
29 this.title_
= /** @type {HTMLElement} */
30 (titleBar
.querySelector('.window-title'));
31 base
.debug
.assert(this.title_
!= null);
33 /** @private {HTMLElement} */
34 this.maximizeRestoreControl_
= /** @type {HTMLElement} */
35 (titleBar
.querySelector('.window-maximize-restore'));
36 base
.debug
.assert(this.maximizeRestoreControl_
!= null);
38 var optionsButton
= titleBar
.querySelector('.window-options');
39 base
.debug
.assert(optionsButton
!= null);
40 this.optionMenuButton_
= new remoting
.MenuButton(
42 this.onShowOptionsMenu_
.bind(this),
43 this.onHideOptionsMenu_
.bind(this));
45 /** @private {HTMLElement} */
46 this.optionsMenuList_
= /** @type {HTMLElement} */
47 (optionsButton
.querySelector('.window-options-menu'));
48 base
.debug
.assert(this.optionsMenuList_
!= null);
51 * @type {Array<{cls:string, fn: function()}>}
54 { cls
: 'window-disconnect', fn
: disconnectCallback
},
55 { cls
: 'window-maximize-restore',
56 fn
: this.maximizeOrRestoreWindow_
.bind(this) },
57 { cls
: 'window-minimize', fn
: this.minimizeWindow_
.bind(this) },
58 { cls
: 'window-close', fn
: remoting
.app
.quit
.bind(remoting
.app
) },
59 { cls
: 'window-controls-stub', fn
: this.toggleWindowControls_
.bind(this) }
61 for (var i
= 0; i
< handlers
.length
; ++i
) {
62 var element
= titleBar
.querySelector('.' + handlers
[i
].cls
);
63 base
.debug
.assert(element
!= null);
64 element
.addEventListener('click', handlers
[i
].fn
, false);
67 // Ensure that tool-tips are always correct.
68 this.handleWindowStateChange_();
69 chrome
.app
.window
.current().onMaximized
.addListener(
70 this.handleWindowStateChange_
.bind(this));
71 chrome
.app
.window
.current().onRestored
.addListener(
72 this.handleWindowStateChange_
.bind(this));
73 chrome
.app
.window
.current().onFullscreened
.addListener(
74 this.handleWindowStateChange_
.bind(this));
75 chrome
.app
.window
.current().onFullscreened
.addListener(
76 this.showWindowControlsPreview_
.bind(this));
80 * @return {remoting.OptionsMenu}
82 remoting
.WindowFrame
.prototype.createOptionsMenu = function() {
83 return new remoting
.OptionsMenu(
84 this.titleBar_
.querySelector('.menu-send-ctrl-alt-del'),
85 this.titleBar_
.querySelector('.menu-send-print-screen'),
86 this.titleBar_
.querySelector('.menu-resize-to-client'),
87 this.titleBar_
.querySelector('.menu-shrink-to-fit'),
88 this.titleBar_
.querySelector('.menu-new-connection'),
89 this.titleBar_
.querySelector('.window-fullscreen'),
90 this.titleBar_
.querySelector('.menu-toggle-connection-stats'),
91 this.titleBar_
.querySelector('.menu-start-stop-recording'));
95 * @param {remoting.DesktopConnectedView} desktopConnectedView The view for the
96 * current session, or null if there is no connection.
98 remoting
.WindowFrame
.prototype.setDesktopConnectedView = function(
99 desktopConnectedView
) {
100 this.desktopConnectedView_
= desktopConnectedView
;
101 var windowTitle
= document
.head
.querySelector('title');
102 if (this.desktopConnectedView_
) {
103 this.title_
.innerText
= desktopConnectedView
.getHostDisplayName();
104 windowTitle
.innerText
= desktopConnectedView
.getHostDisplayName() + ' - ' +
105 remoting
.app
.getApplicationName();
107 this.title_
.innerHTML
= ' ';
108 windowTitle
.innerText
= remoting
.app
.getApplicationName();
110 this.handleWindowStateChange_();
114 * @return {{width: number, height: number}} The size of the window, ignoring
115 * the title-bar and window borders, if visible.
117 remoting
.WindowFrame
.prototype.getClientArea = function() {
118 if (chrome
.app
.window
.current().isFullscreen()) {
119 return { 'height': window
.innerHeight
, 'width': window
.innerWidth
};
121 var kBorderWidth
= 1;
122 var titleHeight
= this.titleBar_
.clientHeight
;
124 'height': window
.innerHeight
- titleHeight
- 2 * kBorderWidth
,
125 'width': window
.innerWidth
- 2 * kBorderWidth
133 remoting
.WindowFrame
.prototype.maximizeOrRestoreWindow_ = function() {
134 /** @type {boolean} */
136 chrome
.app
.window
.current().isFullscreen() ||
137 chrome
.app
.window
.current().isMaximized();
139 chrome
.app
.window
.current().restore();
141 chrome
.app
.window
.current().maximize();
148 remoting
.WindowFrame
.prototype.minimizeWindow_ = function() {
149 chrome
.app
.window
.current().minimize();
155 remoting
.WindowFrame
.prototype.toggleWindowControls_ = function() {
156 this.titleBar_
.classList
.toggle('opened');
160 * Update the tool-top for the maximize/full-screen/restore icon to reflect
161 * its current behaviour.
165 remoting
.WindowFrame
.prototype.handleWindowStateChange_ = function() {
166 // Set the title for the maximize/restore/full-screen button
167 /** @type {string} */
169 if (chrome
.app
.window
.current().isFullscreen()) {
170 tag
= /*i18n-content*/'EXIT_FULL_SCREEN';
171 } else if (chrome
.app
.window
.current().isMaximized()) {
172 tag
= /*i18n-content*/'RESTORE_WINDOW';
174 tag
= /*i18n-content*/'MAXIMIZE_WINDOW';
176 this.maximizeRestoreControl_
.title
= l10n
.getTranslationOrError(tag
);
178 // Ensure that the options menu aligns correctly for the side of the window
180 if (chrome
.app
.window
.current().isFullscreen()) {
181 this.optionsMenuList_
.classList
.add('right-align');
183 this.optionsMenuList_
.classList
.remove('right-align');
188 * Callback invoked when the options menu is shown.
191 remoting
.WindowFrame
.prototype.onShowOptionsMenu_ = function() {
192 remoting
.optionsMenu
.onShow();
193 this.titleBar_
.classList
.add('menu-opened');
197 * Callback invoked when the options menu is shown.
200 remoting
.WindowFrame
.prototype.onHideOptionsMenu_ = function() {
201 this.titleBar_
.classList
.remove('menu-opened');
205 * Show the window controls for a few seconds
209 remoting
.WindowFrame
.prototype.showWindowControlsPreview_ = function() {
211 * @type {HTMLElement}
213 var target
= this.titleBar_
;
214 var kPreviewTimeoutMs
= 3000;
215 var hidePreview = function() {
216 target
.classList
.remove('preview');
218 target
.classList
.add('preview');
219 window
.setTimeout(hidePreview
, kPreviewTimeoutMs
);
223 /** @type {remoting.WindowFrame} */
224 remoting
.windowFrame
= null;