Commit 3f41afcd authored by Jesse Schettler's avatar Jesse Schettler Committed by Commit Bot

scanning: Add dropdown for color mode

Add a new Polymer element, color-mode-select, to display color modes
(e.g. color, black and white, etc.) in a dropdown.

Bug: 1059779
Change-Id: I9bda4b992b0a3a1120a6332c0f3d91c614807b2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453109Reviewed-by: default avatarJimmy Gong <jimmyxgong@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Auto-Submit: Jesse Schettler <jschettler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815388}
parent f8875dff
...@@ -9,7 +9,7 @@ import 'chrome://scanning/scanning_app.js'; ...@@ -9,7 +9,7 @@ import 'chrome://scanning/scanning_app.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {setScanServiceForTesting} from 'chrome://scanning/mojo_interface_provider.js'; import {setScanServiceForTesting} from 'chrome://scanning/mojo_interface_provider.js';
import {ScannerArr} from 'chrome://scanning/scanning_app_types.js'; import {ScannerArr} from 'chrome://scanning/scanning_app_types.js';
import {getSourceTypeString, tokenToString} from 'chrome://scanning/scanning_app_util.js'; import {getColorModeString, getSourceTypeString, tokenToString} from 'chrome://scanning/scanning_app_util.js';
const ColorMode = { const ColorMode = {
BLACK_AND_WHITE: chromeos.scanning.mojom.ColorMode.kBlackAndWhite, BLACK_AND_WHITE: chromeos.scanning.mojom.ColorMode.kBlackAndWhite,
...@@ -245,6 +245,8 @@ suite('ScanningAppTest', () => { ...@@ -245,6 +245,8 @@ suite('ScanningAppTest', () => {
tokenToString(firstScannerId), scanningApp.selectedScannerId); tokenToString(firstScannerId), scanningApp.selectedScannerId);
assertEquals( assertEquals(
firstCapabilities.sources[0].name, scanningApp.selectedSource); firstCapabilities.sources[0].name, scanningApp.selectedSource);
assertEquals(
firstCapabilities.colorModes[0], scanningApp.selectedColorMode);
// Before the scan button is clicked, the settings and scan button // Before the scan button is clicked, the settings and scan button
// should be enabled, and there should be no scan status. // should be enabled, and there should be no scan status.
...@@ -252,6 +254,9 @@ suite('ScanningAppTest', () => { ...@@ -252,6 +254,9 @@ suite('ScanningAppTest', () => {
assertFalse(scannerSelect.disabled); assertFalse(scannerSelect.disabled);
const sourceSelect = scanningApp.$$('#sourceSelect').$$('select'); const sourceSelect = scanningApp.$$('#sourceSelect').$$('select');
assertFalse(sourceSelect.disabled); assertFalse(sourceSelect.disabled);
const colorModeSelect =
scanningApp.$$('#colorModeSelect').$$('select');
assertFalse(colorModeSelect.disabled);
const scanButton = scanningApp.$$('#scanButton'); const scanButton = scanningApp.$$('#scanButton');
assertFalse(scanButton.disabled); assertFalse(scanButton.disabled);
const statusText = scanningApp.$$('#statusText'); const statusText = scanningApp.$$('#statusText');
...@@ -263,6 +268,7 @@ suite('ScanningAppTest', () => { ...@@ -263,6 +268,7 @@ suite('ScanningAppTest', () => {
// scanning is in progress. // scanning is in progress.
assertTrue(scannerSelect.disabled); assertTrue(scannerSelect.disabled);
assertTrue(sourceSelect.disabled); assertTrue(sourceSelect.disabled);
assertTrue(colorModeSelect.disabled);
assertTrue(scanButton.disabled); assertTrue(scanButton.disabled);
assertEquals('Scanning...', statusText.textContent.trim()); assertEquals('Scanning...', statusText.textContent.trim());
return fakeScanService_.whenCalled('scan'); return fakeScanService_.whenCalled('scan');
...@@ -273,6 +279,7 @@ suite('ScanningAppTest', () => { ...@@ -273,6 +279,7 @@ suite('ScanningAppTest', () => {
// complete. // complete.
assertFalse(scanningApp.$$('#scannerSelect').$$('select').disabled); assertFalse(scanningApp.$$('#scannerSelect').$$('select').disabled);
assertFalse(scanningApp.$$('#sourceSelect').$$('select').disabled); assertFalse(scanningApp.$$('#sourceSelect').$$('select').disabled);
assertFalse(scanningApp.$$('#colorModeSelect').$$('select').disabled);
assertFalse(scanningApp.$$('#scanButton').disabled); assertFalse(scanningApp.$$('#scanButton').disabled);
assertEquals( assertEquals(
'Scan complete! File(s) saved to My files.', 'Scan complete! File(s) saved to My files.',
...@@ -431,3 +438,65 @@ suite('SourceSelectTest', () => { ...@@ -431,3 +438,65 @@ suite('SourceSelectTest', () => {
assertFalse(select.disabled); assertFalse(select.disabled);
}); });
}); });
suite('ColorModeSelectTest', () => {
/** @type {!ColorModeSelectElement} */
let colorModeSelect;
setup(() => {
colorModeSelect = document.createElement('color-mode-select');
assertTrue(!!colorModeSelect);
document.body.appendChild(colorModeSelect);
});
teardown(() => {
colorModeSelect.remove();
colorModeSelect = null;
});
test('initializeColorModeSelect', () => {
// Before options are added, the dropdown should be disabled and empty.
const select = colorModeSelect.$$('select');
assertTrue(!!select);
assertTrue(select.disabled);
assertEquals(0, select.length);
const firstColorMode = ColorMode.COLOR;
const secondColorMode = ColorMode.GRAYSCALE;
colorModeSelect.colorModes = [firstColorMode, secondColorMode];
flush();
// Verify that adding more than one color mode results in the dropdown
// becoming enabled with the correct options.
assertFalse(select.disabled);
assertEquals(2, select.length);
assertEquals(
getColorModeString(firstColorMode),
select.options[0].textContent.trim());
assertEquals(
getColorModeString(secondColorMode),
select.options[1].textContent.trim());
assertEquals(firstColorMode.toString(), select.value);
});
test('colorModeSelectDisabled', () => {
const select = colorModeSelect.$$('select');
assertTrue(!!select);
let colorModeArr = [ColorMode.BLACK_AND_WHITE];
colorModeSelect.colorModes = colorModeArr;
flush();
// Verify the dropdown is disabled when there's only one option.
assertEquals(1, select.length);
assertTrue(select.disabled);
colorModeArr = colorModeArr.concat([ColorMode.GRAYSCALE]);
colorModeSelect.colorModes = colorModeArr;
flush();
// Verify the dropdown is enabled when there's more than one option.
assertEquals(2, select.length);
assertFalse(select.disabled);
});
});
...@@ -472,6 +472,9 @@ Try tapping the mic to ask me anything. ...@@ -472,6 +472,9 @@ Try tapping the mic to ask me anything.
<message name="IDS_SCANNING_APP_SOURCE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available scan sources (e.g. flatbed, document feeder, etc.)."> <message name="IDS_SCANNING_APP_SOURCE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available scan sources (e.g. flatbed, document feeder, etc.).">
Source Source
</message> </message>
<message name="IDS_SCANNING_APP_COLOR_MODE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available color modes (e.g. color, grayscale, black and white, etc.).">
Color mode
</message>
<!-- Diagnostics App --> <!-- Diagnostics App -->
<!-- TODO(michaelcheco): Update with finalized copies of the strings --> <!-- TODO(michaelcheco): Update with finalized copies of the strings -->
......
e66b253a61fcc053cb6f7d3eaae4f7d826477a69
\ No newline at end of file
...@@ -10,6 +10,7 @@ import("//tools/polymer/html_to_js.gni") ...@@ -10,6 +10,7 @@ import("//tools/polymer/html_to_js.gni")
js_type_check("closure_compile_module") { js_type_check("closure_compile_module") {
is_polymer3 = true is_polymer3 = true
deps = [ deps = [
":color_mode_select",
":mojo_interface_provider", ":mojo_interface_provider",
":scanner_select", ":scanner_select",
":scanning_app", ":scanning_app",
...@@ -19,6 +20,15 @@ js_type_check("closure_compile_module") { ...@@ -19,6 +20,15 @@ js_type_check("closure_compile_module") {
] ]
} }
js_library("color_mode_select") {
deps = [
":scanning_app_util",
"//chromeos/components/scanning/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
]
}
js_library("scanner_select") { js_library("scanner_select") {
deps = [ deps = [
":scanning_app_types", ":scanning_app_types",
...@@ -31,6 +41,7 @@ js_library("scanner_select") { ...@@ -31,6 +41,7 @@ js_library("scanner_select") {
js_library("scanning_app") { js_library("scanning_app") {
deps = [ deps = [
":color_mode_select",
":mojo_interface_provider", ":mojo_interface_provider",
":scanner_select", ":scanner_select",
":scanning_app_types", ":scanning_app_types",
...@@ -64,6 +75,7 @@ js_library("mojo_interface_provider") { ...@@ -64,6 +75,7 @@ js_library("mojo_interface_provider") {
html_to_js("web_components") { html_to_js("web_components") {
js_files = [ js_files = [
"color_mode_select.js",
"scanner_select.js", "scanner_select.js",
"scanning_app.js", "scanning_app.js",
"source_select.js", "source_select.js",
......
<style>
#title {
height: 32px;
padding-inline-end: 10px;
}
#controls {
display: inline-block;
height: 32px;
width: 300px;
}
</style>
<span id="title">[[i18n('colorModeDropdownLabel')]]</span>
<div id="controls">
<!-- TODO(jschettler): Verify this meets a11y expecations (e.g. ChromeVox
should announce when a new option is focused). -->
<select class="md-select" value="{{selectedColorMode::change}}"
disabled="[[disabled_]]">
<!-- TODO(jschettler): Determine how the color modes should be sorted. -->
<template is="dom-repeat" items="[[colorModes]]" as="colorMode">
<option value="[[colorMode]]">
[[getColorModeString_(colorMode)]]
</option>
</template>
</select>
</div>
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import './scanning.mojom-lite.js';
import {getColorModeString} from './scanning_app_util.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import './strings.js';
/** @type {number} */
const NUM_REQUIRED_COLOR_MODES = 2;
/**
* @fileoverview
* 'color-mode-select' displays the available scanner color modes in a dropdown.
*/
Polymer({
is: 'color-mode-select',
_template: html`{__html_template__}`,
behaviors: [I18nBehavior],
properties: {
/** @type {!Array<chromeos.scanning.mojom.ColorMode>} */
colorModes: {
type: Array,
value: () => [],
},
/** @type {chromeos.scanning.mojom.ColorMode|undefined} */
selectedColorMode: {
type: chromeos.scanning.mojom.ColorMode,
notify: true,
},
settingsDisabled: Boolean,
/** @private */
disabled_: Boolean,
},
observers: [
'updateDisabled_(colorModes.length, settingsDisabled)',
],
/**
* @param {number} mojoColorMode
* @return {!string}
* @private
*/
getColorModeString_(mojoColorMode) {
return getColorModeString(mojoColorMode);
},
/**
* Disables the dropdown if settings are disabled or the number of available
* color modes is less than the number of required color modes.
* @private
*/
updateDisabled_() {
this.disabled_ = this.settingsDisabled ||
this.colorModes.length < NUM_REQUIRED_COLOR_MODES;
},
});
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
settings-disabled="[[settingsDisabled_]]" settings-disabled="[[settingsDisabled_]]"
selected-source="{{selectedSource}}"></source-select> selected-source="{{selectedSource}}"></source-select>
</div> </div>
<div>
<color-mode-select id="colorModeSelect"
color-modes="[[capabilities_.colorModes]]"
settings-disabled="[[settingsDisabled_]]"
selected-color-mode="{{selectedColorMode}}"></color-mode-select>
</div>
<!-- TODO(jschettler): Replace button label with finalized i18n string. --> <!-- TODO(jschettler): Replace button label with finalized i18n string. -->
<cr-button id="scanButton" on-click="onScanClick_" <cr-button id="scanButton" on-click="onScanClick_"
disabled$="[[scanButtonDisabled_]]"> disabled$="[[scanButtonDisabled_]]">
......
...@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; ...@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
import 'chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js'; import 'chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js';
import 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js'; import 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js';
import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js'; import 'chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js';
import './color_mode_select.js';
import './scanner_select.js'; import './scanner_select.js';
import './source_select.js'; import './source_select.js';
...@@ -51,6 +52,9 @@ Polymer({ ...@@ -51,6 +52,9 @@ Polymer({
/** @type {?string} */ /** @type {?string} */
selectedSource: String, selectedSource: String,
/** @type {chromeos.scanning.mojom.ColorMode|undefined} */
selectedColorMode: chromeos.scanning.mojom.ColorMode,
/** /**
* @type {?string} * @type {?string}
* @private * @private
...@@ -99,9 +103,10 @@ Polymer({ ...@@ -99,9 +103,10 @@ Polymer({
onCapabilitiesReceived_(response) { onCapabilitiesReceived_(response) {
this.capabilities_ = response.capabilities; this.capabilities_ = response.capabilities;
// Set the first source as the selected source since it will be the first // Set the first options as the selected options since they will be the
// option in the dropdown. // first options in the dropdowns.
this.selectedSource = this.capabilities_.sources[0].name; this.selectedSource = this.capabilities_.sources[0].name;
this.selectedColorMode = this.capabilities_.colorModes[0];
this.scanButtonDisabled_ = false; this.scanButtonDisabled_ = false;
}, },
...@@ -150,7 +155,8 @@ Polymer({ ...@@ -150,7 +155,8 @@ Polymer({
/** @private */ /** @private */
onScanClick_() { onScanClick_() {
if (!this.selectedScannerId || !this.selectedSource) { if (!this.selectedScannerId || !this.selectedSource ||
this.selectedColorMode === undefined) {
// TODO(jschettler): Replace status text with finalized i18n strings. // TODO(jschettler): Replace status text with finalized i18n strings.
this.statusText_ = 'Failed to start scan.'; this.statusText_ = 'Failed to start scan.';
return; return;
...@@ -160,11 +166,11 @@ Polymer({ ...@@ -160,11 +166,11 @@ Polymer({
this.settingsDisabled_ = true; this.settingsDisabled_ = true;
this.scanButtonDisabled_ = true; this.scanButtonDisabled_ = true;
// TODO(jschettler): Set color mode and resolution using the selected values // TODO(jschettler): Set resolution using the selected value when the
// when the corresponding dropdowns are added. // corresponding dropdowns are added.
const settings = { const settings = {
'sourceName': this.selectedSource, 'sourceName': this.selectedSource,
'colorMode': chromeos.scanning.mojom.ColorMode.kColor, 'colorMode': this.selectedColorMode,
'resolutionDpi': 100, 'resolutionDpi': 100,
}; };
this.scanService_ this.scanService_
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<include name="IDR_SCANNING_APP_SCANNER_SELECT_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/scanner_select.js" use_base_dir="false" compress="gzip" type="BINDATA"/> <include name="IDR_SCANNING_APP_SCANNER_SELECT_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/scanner_select.js" use_base_dir="false" compress="gzip" type="BINDATA"/>
<include name="IDR_SCANNING_APP_SOURCE_SELECT_HTML" file="source_select.html" compress="gzip" type="BINDATA"/> <include name="IDR_SCANNING_APP_SOURCE_SELECT_HTML" file="source_select.html" compress="gzip" type="BINDATA"/>
<include name="IDR_SCANNING_APP_SOURCE_SELECT_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/source_select.js" use_base_dir="false" compress="gzip" type="BINDATA"/> <include name="IDR_SCANNING_APP_SOURCE_SELECT_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/source_select.js" use_base_dir="false" compress="gzip" type="BINDATA"/>
<include name="IDR_SCANNING_APP_COLOR_MODE_SELECT_HTML" file="color_mode_select.html" compress="gzip" type="BINDATA"/>
<include name="IDR_SCANNING_APP_COLOR_MODE_SELECT_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/color_mode_select.js" use_base_dir="false" compress="gzip" type="BINDATA"/>
<include name="IDR_SCANNING_APP_THROBBER_CSS_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/throbber_css.js" use_base_dir="false" type="BINDATA"/> <include name="IDR_SCANNING_APP_THROBBER_CSS_JS" file="${root_gen_dir}/chromeos/components/scanning/resources/throbber_css.js" use_base_dir="false" type="BINDATA"/>
<include name="IDR_SCANNING_APP_ICON" file="app_icon_192.png" type="BINDATA" /> <include name="IDR_SCANNING_APP_ICON" file="app_icon_192.png" type="BINDATA" />
</includes> </includes>
......
...@@ -4,6 +4,27 @@ ...@@ -4,6 +4,27 @@
import {assertNotReached} from 'chrome://resources/js/assert.m.js'; import {assertNotReached} from 'chrome://resources/js/assert.m.js';
/**
* Converts a chromeos.scanning.mojom.ColorMode to a string that can be
* displayed in the color mode dropdown.
* @param {number} mojoColorMode
* @return {!string}
*/
export function getColorModeString(mojoColorMode) {
// TODO(jschettler): Replace with finalized i18n strings.
switch (mojoColorMode) {
case chromeos.scanning.mojom.ColorMode.kBlackAndWhite:
return 'Black and White';
case chromeos.scanning.mojom.ColorMode.kGrayscale:
return 'Grayscale';
case chromeos.scanning.mojom.ColorMode.kColor:
return 'Color';
default:
assertNotReached();
return 'Unknown';
}
}
/** /**
* Converts a chromeos.scanning.mojom.SourceType to a string that can be * Converts a chromeos.scanning.mojom.SourceType to a string that can be
* displayed in the source dropdown. * displayed in the source dropdown.
......
...@@ -51,7 +51,8 @@ void AddScanningAppStrings(content::WebUIDataSource* html_source) { ...@@ -51,7 +51,8 @@ void AddScanningAppStrings(content::WebUIDataSource* html_source) {
{"appTitle", IDS_SCANNING_APP_TITLE}, {"appTitle", IDS_SCANNING_APP_TITLE},
{"scannerDropdownLabel", IDS_SCANNING_APP_SCANNER_DROPDOWN_LABEL}, {"scannerDropdownLabel", IDS_SCANNING_APP_SCANNER_DROPDOWN_LABEL},
{"noScannersText", IDS_SCANNING_APP_NO_SCANNERS_TEXT}, {"noScannersText", IDS_SCANNING_APP_NO_SCANNERS_TEXT},
{"sourceDropdownLabel", IDS_SCANNING_APP_SOURCE_DROPDOWN_LABEL}}; {"sourceDropdownLabel", IDS_SCANNING_APP_SOURCE_DROPDOWN_LABEL},
{"colorModeDropdownLabel", IDS_SCANNING_APP_COLOR_MODE_DROPDOWN_LABEL}};
for (const auto& str : kLocalizedStrings) for (const auto& str : kLocalizedStrings)
html_source->AddLocalizedString(str.name, str.id); html_source->AddLocalizedString(str.name, str.id);
......
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