Commit 983cb2f7 authored by jamiewalch's avatar jamiewalch Committed by Commit bot

Separate menu & disconnect buttons from the window controls and clean up CSS.

One piece of feedback we've received is that users want an
explicit full-screen control rather than tying it to
maximize. Simply adding a full-screen button means that the
window has six icons of varying crypticness (crypticality?)

This CL prepares the ground for adding a full-screen button
while reducing clutter. It moves the Options and Disconnect
buttons to the left-hand side of the window, while leaving
them adjacent to the window controls in full-screen mode.

There are two main changes to the CSS. The first is that we
no longer use "display: table"; I thought this was needed to
get rid of the implicit spaces between the icons, but
"display: flex" does the job just as well. The second is to
do with how the etched borders are rendered. Previously, a
button was responsible for rending both the light and dark
highlights to the left and bottom. This worked because they
were all right-aligned, but with the new layout, each button
renders all of its borders.

Review URL: https://codereview.chromium.org/498813003

Cr-Commit-Position: refs/heads/master@{#291745}
parent 4739a2c5
......@@ -21,7 +21,7 @@ found in the LICENSE file.
<title i18n-content="PRODUCT_NAME"></title>
</head>
<body class="full-height inner-border-for-apps-v2">
<body class="full-height">
<meta-include src="webapp/html/window_frame.html"/>
......
......@@ -4,54 +4,52 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<div id="title-bar" class="title-bar apps-v2-only">
<span class="window-title">&nbsp;</span>
<span class="window-controls-hover-target">
<div class="window-controls">
<span i18n-title="OPTIONS_MENU"
class="window-control window-options menu-button">
<span class="menu-button-activator">
<img src="icon_options.webp">
</span>
<ul class="window-options-menu right-align">
<li class="menu-start-stop-recording"
i18n-content="START_RECORDING"
hidden></li>
<li class="menu-send-ctrl-alt-del"
i18n-content="SEND_CTRL_ALT_DEL"></li>
<li class="menu-send-print-screen"
i18n-content="SEND_PRINT_SCREEN"></li>
<li class="menu-separator"></li>
<li class="menu-resize-to-client"
i18n-content="RESIZE_TO_CLIENT"></li>
<li class="menu-shrink-to-fit"
i18n-content="SHRINK_TO_FIT"></li>
<li class="menu-separator"></li>
<li class="menu-new-connection"
i18n-content="NEW_CONNECTION"></li>
<li class="menu-separator"></li>
<li class="menu-help"
i18n-content="HELP"></li>
<li class="menu-feedback"
i18n-content="ACTIONBAR_FEEDBACK"></li>
</ul>
<div class="window-controls-and-title">
<span i18n-title="OPTIONS_MENU"
class="window-control window-options menu-button">
<span class="menu-button-activator">
<img src="icon_options.webp">
</span>
<span i18n-title="DISCONNECT_MYSELF_BUTTON"
class="window-control window-disconnect">
<img src="icon_disconnect.webp">
</span>
<span i18n-title="MINIMIZE_WINDOW"
class="window-control window-minimize">
<img src="icon_minimize.webp">
</span>
<span i18n-title="MAXIMIZE_WINDOW"
class="window-control window-maximize-restore">
<img src="icon_maximize_restore.webp">
</span>
<span i18n-title="CLOSE_WINDOW"
class="window-control window-close">
<img src="icon_close.webp">
</span>
</div>
<div class="window-controls-stub">&nbsp;</div>
</span>
</div>
<ul class="window-options-menu right-align">
<li class="menu-start-stop-recording"
i18n-content="START_RECORDING"
hidden></li>
<li class="menu-send-ctrl-alt-del"
i18n-content="SEND_CTRL_ALT_DEL"></li>
<li class="menu-send-print-screen"
i18n-content="SEND_PRINT_SCREEN"></li>
<li class="menu-separator"></li>
<li class="menu-resize-to-client"
i18n-content="RESIZE_TO_CLIENT"></li>
<li class="menu-shrink-to-fit"
i18n-content="SHRINK_TO_FIT"></li>
<li class="menu-separator"></li>
<li class="menu-new-connection"
i18n-content="NEW_CONNECTION"></li>
<li class="menu-separator"></li>
<li class="menu-help"
i18n-content="HELP"></li>
<li class="menu-feedback"
i18n-content="ACTIONBAR_FEEDBACK"></li>
</ul>
</span>
<span i18n-title="DISCONNECT_MYSELF_BUTTON"
class="window-control window-disconnect">
<img src="icon_disconnect.webp">
</span>
<span class="window-title">&nbsp;</span>
<span i18n-title="MINIMIZE_WINDOW"
class="window-control window-minimize">
<img src="icon_minimize.webp">
</span>
<span i18n-title="MAXIMIZE_WINDOW"
class="window-control window-maximize-restore">
<img src="icon_maximize_restore.webp">
</span>
<span i18n-title="CLOSE_WINDOW"
class="window-control window-close">
<img src="icon_close.webp">
</span>
</div>
<div class="window-controls-stub">&nbsp;</div>
</div> <!-- title-bar -->
......@@ -13,17 +13,19 @@ html.apps-v2 body:not(.fullscreen) {
border: 1px solid gray; /* This is the window border. */
}
html.apps-v2 .title-bar {
border-bottom: 1px solid gray;
.title-bar {
z-index: 100;
width: 100%;
background-color: #c4c4c4;
}
.window-title,
.window-controls-hover-target {
height: 32px;
.window-controls-and-title {
display: flex;
}
.window-title {
line-height: 32px;
font-size: 14px;
background-color: #c4c4c4;
}
.title-bar .window-title {
......@@ -31,29 +33,16 @@ html.apps-v2 .title-bar {
width: 100%;
display: inline-block;
-webkit-app-region: drag;
}
.window-controls-hover-target {
-webkit-app-region: no-drag;
position: fixed;
top: 1px;
__MSG_@@bidi_end_edge__: 1px;
}
.window-controls-hover-target {
display: table;
}
.window-controls-hover-target > div:first-child {
display: table-row;
flex: 1;
}
.window-control {
height: 32px;
width: 32px;
height: 32px;
padding-top: 9px;
padding-right: 1px;
text-align: center;
display: inline-block;
border-__MSG_@@bidi_start_edge__: 1px solid rgba(0, 0, 0, 0.2);
}
.window-control > span.menu-button-activator {
......@@ -76,10 +65,9 @@ html.apps-v2 .title-bar {
.window-controls-stub {
display: none;
-webkit-column-span: all;
line-height: 3px;
height: 8px;
background: url("drag.webp");
border-top: 1px solid rgba(0, 0, 0, 0.2);
background-position: 2px 1px;
}
#scroller {
......@@ -90,30 +78,42 @@ html.apps-v2 .title-bar {
}
html.apps-v2 #scroller {
height: calc(100% - 32px); /** Allow space for the title-bar */
height: calc(100% - 32px); /* Allow space for the title-bar */
}
/* Add an etched border to the window controls, title bar and stub */
.title-bar,
.window-title,
.window-control,
.window-controls-stub {
position: relative;
}
.title-bar:after,
.window-control:after,
.window-controls-stub:after {
.window-title::after,
.window-control::after,
.window-controls-stub::after {
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border-left: 1px solid rgba(255, 255, 255, 0.2);
border-right: 1px solid rgba(0, 0, 0, 0.2);
border-top: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(0, 0, 0, 0.3); /* darken bottom slightly */
border-left: 1px solid rgba(255, 255, 255, 0.2);
pointer-events: none;
box-sizing: border-box;
}
/* Remove dark borders for elements that are adjacent an existing border. */
.window-close::after {
border-right: none;
}
.window-controls-stub::after {
border-bottom: none;
border-right: none;
}
/* The Disconnect and Options buttons are only displayed when connected. */
body:not(.connected) .window-disconnect,
......@@ -127,7 +127,7 @@ body:not(.connected) .window-options {
* - The scroll-bars are removed.
* - The window controls have a border (so the left-border of the first button
* is not needed).
* - The title-bar (and its bottom border) are not displayed.
* - The window title is not displayed.
* - The stub is visible.
* - The window controls gain transition effects for position and opacity and
* auto-hide behind the top edge of the screen.
......@@ -141,27 +141,28 @@ html.apps-v2 body.fullscreen #scroller {
overflow: hidden;
}
body.fullscreen .window-controls-hover-target {
body.fullscreen .title-bar {
border: 1px solid #a6a6a6;
}
body.fullscreen .window-control:first-child {
border-__MSG_@@bidi_start_edge__: none;
}
body.fullscreen .window-title {
display: none;
}
body.fullscreen .title-bar {
border-bottom: none;
position: fixed;
width: initial; /* Override the 100% width when windowed. */
}
body.fullscreen .window-controls-and-title {
display: inline-flex;
}
body.fullscreen .window-controls-stub {
display: table-cell;
display: block;
}
body.fullscreen .window-controls-hover-target {
body.fullscreen .title-bar {
transition-property: opacity, box-shadow, top;
transition-duration: 0.3s;
opacity: 0.7;
......@@ -169,15 +170,15 @@ body.fullscreen .window-controls-hover-target {
__MSG_@@bidi_end_edge__: 8px;
}
body.fullscreen .window-controls-hover-target:hover,
body.fullscreen .window-controls-hover-target.menu-opened,
body.fullscreen .window-controls-hover-target.opened,
body.fullscreen .window-controls-hover-target.preview {
body.fullscreen .title-bar:hover,
body.fullscreen .title-bar.menu-opened,
body.fullscreen .title-bar.opened,
body.fullscreen .title-bar.preview {
top: -4px;
opacity: 1.0;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.5);
}
.fullscreen .window-controls-hover-target.opened .window-controls-stub {
.fullscreen .title-bar.opened .window-controls-stub {
background-color: #a6a6a6;
}
......@@ -29,14 +29,6 @@ remoting.WindowFrame = function(titleBar) {
*/
this.titleBar_ = titleBar;
/**
* @type {HTMLElement}
* @private
*/
this.hoverTarget_ = /** @type {HTMLElement} */
(titleBar.querySelector('.window-controls-hover-target'));
base.debug.assert(this.hoverTarget_ != null);
/**
* @type {remoting.OptionsMenu}
* @private
......@@ -73,6 +65,14 @@ remoting.WindowFrame = function(titleBar) {
this.onShowOptionsMenu_.bind(this),
this.onHideOptionsMenu_.bind(this));
/**
* @type {HTMLElement}
* @private
*/
this.optionsMenuList_ = /** @type {HTMLElement} */
(optionsButton.querySelector('.window-options-menu'));
base.debug.assert(this.optionsMenu_ != null);
/**
* @type {Array.<{cls:string, fn: function()}>}
*/
......@@ -91,13 +91,13 @@ remoting.WindowFrame = function(titleBar) {
}
// Ensure that tool-tips are always correct.
this.updateMaximizeOrRestoreIconTitle_();
this.handleWindowStateChange_();
chrome.app.window.current().onMaximized.addListener(
this.updateMaximizeOrRestoreIconTitle_.bind(this));
this.handleWindowStateChange_.bind(this));
chrome.app.window.current().onRestored.addListener(
this.updateMaximizeOrRestoreIconTitle_.bind(this));
this.handleWindowStateChange_.bind(this));
chrome.app.window.current().onFullscreened.addListener(
this.updateMaximizeOrRestoreIconTitle_.bind(this));
this.handleWindowStateChange_.bind(this));
chrome.app.window.current().onFullscreened.addListener(
this.showWindowControlsPreview_.bind(this));
};
......@@ -119,7 +119,7 @@ remoting.WindowFrame.prototype.setClientSession = function(clientSession) {
windowTitle.innerText =
chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
}
this.updateMaximizeOrRestoreIconTitle_();
this.handleWindowStateChange_();
};
/**
......@@ -185,7 +185,7 @@ remoting.WindowFrame.prototype.minimizeWindow_ = function() {
* @private
*/
remoting.WindowFrame.prototype.toggleWindowControls_ = function() {
this.hoverTarget_.classList.toggle('opened');
this.titleBar_.classList.toggle('opened');
};
/**
......@@ -194,7 +194,8 @@ remoting.WindowFrame.prototype.toggleWindowControls_ = function() {
*
* @private
*/
remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() {
remoting.WindowFrame.prototype.handleWindowStateChange_ = function() {
// Set the title for the maximize/restore/full-screen button
/** @type {string} */
var tag = '';
if (chrome.app.window.current().isFullscreen()) {
......@@ -207,6 +208,14 @@ remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() {
tag = /*i18n-content*/'MAXIMIZE_WINDOW';
}
this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag);
// Ensure that the options menu aligns correctly for the side of the window
// it occupies.
if (chrome.app.window.current().isFullscreen()) {
this.optionsMenuList_.classList.add('right-align');
} else {
this.optionsMenuList_.classList.remove('right-align');
}
};
/**
......@@ -215,7 +224,7 @@ remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() {
*/
remoting.WindowFrame.prototype.onShowOptionsMenu_ = function() {
this.optionsMenu_.onShow();
this.hoverTarget_.classList.add('menu-opened');
this.titleBar_.classList.add('menu-opened');
};
/**
......@@ -223,7 +232,7 @@ remoting.WindowFrame.prototype.onShowOptionsMenu_ = function() {
* @private
*/
remoting.WindowFrame.prototype.onHideOptionsMenu_ = function() {
this.hoverTarget_.classList.remove('menu-opened');
this.titleBar_.classList.remove('menu-opened');
};
/**
......@@ -235,7 +244,7 @@ remoting.WindowFrame.prototype.showWindowControlsPreview_ = function() {
/**
* @type {HTMLElement}
*/
var target = this.hoverTarget_;
var target = this.titleBar_;
var kPreviewTimeoutMs = 3000;
var hidePreview = function() {
target.classList.remove('preview');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment