Commit bc725525 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Add a blinking braille cursor

Bug: 851654
Cq-Include-Trybots: luci.chromium.try:closure_compilation
Change-Id: Ic3ef45567f53eef44a92e0adb51ef592a9e5bfe2
Reviewed-on: https://chromium-review.googlesource.com/1132117Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574199}
parent 33156fc8
...@@ -103,9 +103,8 @@ cvox.BrailleDisplayManager = function(translatorManager) { ...@@ -103,9 +103,8 @@ cvox.BrailleDisplayManager = function(translatorManager) {
/** /**
* Dots representing a cursor. * Dots representing a cursor.
* @const * @const
* @private
*/ */
cvox.BrailleDisplayManager.CURSOR_DOTS_ = 1 << 6 | 1 << 7; cvox.BrailleDisplayManager.CURSOR_DOTS = 1 << 6 | 1 << 7;
/** /**
...@@ -139,6 +138,14 @@ cvox.BrailleDisplayManager.COORDS_TO_BRAILLE_DOT_ = ...@@ -139,6 +138,14 @@ cvox.BrailleDisplayManager.COORDS_TO_BRAILLE_DOT_ =
[0x1, 0x2, 0x4, 0x40, 0x8, 0x10, 0x20, 0x80]; [0x1, 0x2, 0x4, 0x40, 0x8, 0x10, 0x20, 0x80];
/**
* Time elapsed before a cursor changes state. This results in a blinking
* effect.
* @const {number}
*/
cvox.BrailleDisplayManager.CURSOR_BLINK_TIME_MS = 1000;
/** /**
* @param {!cvox.NavBraille} content Content to send to the braille display. * @param {!cvox.NavBraille} content Content to send to the braille display.
* @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
...@@ -310,10 +317,29 @@ cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() { ...@@ -310,10 +317,29 @@ cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() {
* @private * @private
*/ */
cvox.BrailleDisplayManager.prototype.refresh_ = function() { cvox.BrailleDisplayManager.prototype.refresh_ = function() {
if (this.blinkerId_ !== undefined) {
window.clearInterval(this.blinkerId_);
}
this.refreshInternal_(true);
var showCursor = false;
this.blinkerId_ = window.setInterval(function() {
this.refreshInternal_(showCursor);
showCursor = !showCursor;
}.bind(this), cvox.BrailleDisplayManager.CURSOR_BLINK_TIME_MS);
};
/**
* @param {boolean} showCursor Whether to show the cursor.
* @private
*/
cvox.BrailleDisplayManager.prototype.refreshInternal_ = function(showCursor) {
if (!this.displayState_.available) { if (!this.displayState_.available) {
return; return;
} }
var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents(); var brailleBuf =
this.panStrategy_.getCurrentBrailleViewportContents(showCursor);
var textBuf = this.panStrategy_.getCurrentTextViewportContents(); var textBuf = this.panStrategy_.getCurrentTextViewportContents();
if (this.realDisplayState_.available) { if (this.realDisplayState_.available) {
chrome.brailleDisplayPrivate.writeDots( chrome.brailleDisplayPrivate.writeDots(
...@@ -365,9 +391,10 @@ cvox.BrailleDisplayManager.prototype.translateContent_ = function( ...@@ -365,9 +391,10 @@ cvox.BrailleDisplayManager.prototype.translateContent_ = function(
translatedEndIndex = textToBraille[endIndex]; translatedEndIndex = textToBraille[endIndex];
} }
// Add the cursor to cells. // Add the cursor to cells.
this.writeCursor_(cells, translatedStartIndex, translatedEndIndex); this.setCursor_(cells, translatedStartIndex, translatedEndIndex);
targetPosition = translatedStartIndex; targetPosition = translatedStartIndex;
} else { } else {
this.setCursor_(cells, -1, -1);
targetPosition = 0; targetPosition = 0;
} }
this.panStrategy_.setContent( this.panStrategy_.setContent(
...@@ -443,28 +470,23 @@ cvox.BrailleDisplayManager.prototype.panRight_ = function() { ...@@ -443,28 +470,23 @@ cvox.BrailleDisplayManager.prototype.panRight_ = function() {
}; };
/** /**
* Writes a cursor in the specified range into translated content. * Sets a cursor within translated content.
* @param {ArrayBuffer} buffer Buffer to add cursor to. * @param {ArrayBuffer} buffer Buffer to add cursor to.
* @param {number} startIndex The start index to place the cursor. * @param {number} startIndex The start index to place the cursor.
* @param {number} endIndex The end index to place the cursor (exclusive). * @param {number} endIndex The end index to place the cursor (exclusive).
* @private * @private
*/ */
cvox.BrailleDisplayManager.prototype.writeCursor_ = function( cvox.BrailleDisplayManager.prototype.setCursor_ = function(
buffer, startIndex, endIndex) { buffer, startIndex, endIndex) {
if (startIndex < 0 || startIndex >= buffer.byteLength || if (startIndex < 0 || startIndex >= buffer.byteLength ||
endIndex < startIndex || endIndex > buffer.byteLength) { endIndex < startIndex || endIndex > buffer.byteLength) {
this.panStrategy_.setCursor(-1, -1);
return; return;
} }
if (startIndex == endIndex) { if (startIndex == endIndex) {
endIndex = startIndex + 1; endIndex = startIndex + 1;
} }
var dataView = new DataView(buffer); this.panStrategy_.setCursor(startIndex, endIndex);
while (startIndex < endIndex) {
var value = dataView.getUint8(startIndex);
value |= cvox.BrailleDisplayManager.CURSOR_DOTS_;
dataView.setUint8(startIndex, value);
startIndex++;
}
}; };
/** /**
......
...@@ -70,7 +70,7 @@ CvoxBrailleDisplayManagerUnitTest.prototype = { ...@@ -70,7 +70,7 @@ CvoxBrailleDisplayManagerUnitTest.prototype = {
assertEquals(1, this.writtenCells.length); assertEquals(1, this.writtenCells.length);
var a = new Uint8Array(this.writtenCells[0]); var a = new Uint8Array(this.writtenCells[0]);
this.writtenCells.length = 0; this.writtenCells.length = 0;
var firstCell = a[0] & ~cvox.BrailleDisplayManager.CURSOR_DOTS_; var firstCell = a[0] & ~cvox.BrailleDisplayManager.CURSOR_DOTS;
// We are asserting that start, which is an index, and firstCell, // We are asserting that start, which is an index, and firstCell,
// which is a value, are the same because the fakeTranslator generates // which is a value, are the same because the fakeTranslator generates
// the values of the braille cells based on indices. // the values of the braille cells based on indices.
...@@ -78,8 +78,8 @@ CvoxBrailleDisplayManagerUnitTest.prototype = { ...@@ -78,8 +78,8 @@ CvoxBrailleDisplayManagerUnitTest.prototype = {
' Start mismatch: ' + start + ' vs. ' + firstCell); ' Start mismatch: ' + start + ' vs. ' + firstCell);
if (opt_selStart !== undefined) { if (opt_selStart !== undefined) {
for (var i = opt_selStart; i < opt_selEnd; ++i) { for (var i = opt_selStart; i < opt_selEnd; ++i) {
assertEquals(cvox.BrailleDisplayManager.CURSOR_DOTS_, assertEquals(cvox.BrailleDisplayManager.CURSOR_DOTS,
a[i] & cvox.BrailleDisplayManager.CURSOR_DOTS_, a[i] & cvox.BrailleDisplayManager.CURSOR_DOTS,
'Missing cursor marker at position ' + i); 'Missing cursor marker at position ' + i);
} }
} }
......
...@@ -75,6 +75,11 @@ cvox.PanStrategy = function() { ...@@ -75,6 +75,11 @@ cvox.PanStrategy = function() {
*/ */
this.panStrategyWrapped_ = false; this.panStrategyWrapped_ = false;
/** @typedef {{start: (number), end: (number)}} */
this.cursor_ = {start: -1, end: -1};
/** @typedef {{start: (number), end: (number)}} */
this.wrappedCursor_ = {start: -1, end: -1};
}; };
/** /**
...@@ -142,12 +147,39 @@ cvox.PanStrategy.prototype = { ...@@ -142,12 +147,39 @@ cvox.PanStrategy.prototype = {
}, },
/** /**
* @param {boolean=} opt_showCursor Defaults to true.
* @return {ArrayBuffer} Buffer of the slice of braille cells within the * @return {ArrayBuffer} Buffer of the slice of braille cells within the
* bounds of the viewport. * bounds of the viewport.
*/ */
getCurrentBrailleViewportContents: function() { getCurrentBrailleViewportContents: function(opt_showCursor) {
opt_showCursor = opt_showCursor === undefined ? true : opt_showCursor;
var buf = var buf =
this.panStrategyWrapped_ ? this.wrappedBuffer_ : this.fixedBuffer_; this.panStrategyWrapped_ ? this.wrappedBuffer_ : this.fixedBuffer_;
var startIndex, endIndex;
if (this.panStrategyWrapped_) {
startIndex = this.wrappedCursor_.start;
endIndex = this.wrappedCursor_.end;
} else {
startIndex = this.cursor_.start;
endIndex = this.cursor_.end;
}
if (startIndex >= 0 && startIndex < buf.byteLength &&
endIndex >= startIndex && endIndex <= buf.byteLength) {
var dataView = new DataView(buf);
while (startIndex < endIndex) {
var value = dataView.getUint8(startIndex);
if (opt_showCursor) {
value |= cvox.BrailleDisplayManager.CURSOR_DOTS;
} else {
value &= ~cvox.BrailleDisplayManager.CURSOR_DOTS;
}
dataView.setUint8(startIndex, value);
startIndex++;
}
}
return buf.slice( return buf.slice(
this.viewPort_.firstRow * this.displaySize_.columns, this.viewPort_.firstRow * this.displaySize_.columns,
(this.viewPort_.lastRow + 1) * this.displaySize_.columns); (this.viewPort_.lastRow + 1) * this.displaySize_.columns);
...@@ -252,6 +284,8 @@ cvox.PanStrategy.prototype = { ...@@ -252,6 +284,8 @@ cvox.PanStrategy.prototype = {
} else { } else {
// |lastBreak| is at the beginning of a line, so current word is // |lastBreak| is at the beginning of a line, so current word is
// bigger than |this.displaySize_.columns| so we shouldn't wrap. // bigger than |this.displaySize_.columns| so we shouldn't wrap.
this.maybeSetWrappedCursor_(
index - cellsPadded, wrappedBrailleArray.length);
wrappedBrailleArray.push(view[index - cellsPadded]); wrappedBrailleArray.push(view[index - cellsPadded]);
this.wrappedBrailleToText_.push( this.wrappedBrailleToText_.push(
fixedBrailleToText[index - cellsPadded]); fixedBrailleToText[index - cellsPadded]);
...@@ -260,6 +294,8 @@ cvox.PanStrategy.prototype = { ...@@ -260,6 +294,8 @@ cvox.PanStrategy.prototype = {
if (view[index - cellsPadded] == 0) { if (view[index - cellsPadded] == 0) {
lastBreak = index; lastBreak = index;
} }
this.maybeSetWrappedCursor_(
index - cellsPadded, wrappedBrailleArray.length);
wrappedBrailleArray.push(view[index - cellsPadded]); wrappedBrailleArray.push(view[index - cellsPadded]);
this.wrappedBrailleToText_.push( this.wrappedBrailleToText_.push(
fixedBrailleToText[index - cellsPadded]); fixedBrailleToText[index - cellsPadded]);
...@@ -273,6 +309,29 @@ cvox.PanStrategy.prototype = { ...@@ -273,6 +309,29 @@ cvox.PanStrategy.prototype = {
this.panToPosition_(targetPosition); this.panToPosition_(targetPosition);
}, },
/**
* Sets a braille cursor.
* @param {number} startIndex
* @param {number} endIndex
*/
setCursor: function(startIndex, endIndex) {
this.cursor_ = {start: startIndex, end: endIndex};
},
/**
*
*/
maybeSetWrappedCursor_: function(unwrappedIndex, wrappedIndex) {
// We only care about the bounds of the index start/end.
if (this.cursor_.start != unwrappedIndex &&
this.cursor_.end != unwrappedIndex)
return;
if (this.cursor_.start == unwrappedIndex)
this.wrappedCursor_.start = wrappedIndex;
else if (this.cursor_.end == unwrappedIndex)
this.wrappedCursor_.end = wrappedIndex;
},
/** /**
* If possible, changes the viewport to a part of the line that follows * If possible, changes the viewport to a part of the line that follows
* the current viewport. * the current viewport.
......
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