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) {
/**
* Dots representing a cursor.
* @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_ =
[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.ExpandingBrailleTranslator.ExpansionType} expansionType
......@@ -310,10 +317,29 @@ cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() {
* @private
*/
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) {
return;
}
var brailleBuf = this.panStrategy_.getCurrentBrailleViewportContents();
var brailleBuf =
this.panStrategy_.getCurrentBrailleViewportContents(showCursor);
var textBuf = this.panStrategy_.getCurrentTextViewportContents();
if (this.realDisplayState_.available) {
chrome.brailleDisplayPrivate.writeDots(
......@@ -365,9 +391,10 @@ cvox.BrailleDisplayManager.prototype.translateContent_ = function(
translatedEndIndex = textToBraille[endIndex];
}
// Add the cursor to cells.
this.writeCursor_(cells, translatedStartIndex, translatedEndIndex);
this.setCursor_(cells, translatedStartIndex, translatedEndIndex);
targetPosition = translatedStartIndex;
} else {
this.setCursor_(cells, -1, -1);
targetPosition = 0;
}
this.panStrategy_.setContent(
......@@ -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 {number} startIndex The start index to place the cursor.
* @param {number} endIndex The end index to place the cursor (exclusive).
* @private
*/
cvox.BrailleDisplayManager.prototype.writeCursor_ = function(
cvox.BrailleDisplayManager.prototype.setCursor_ = function(
buffer, startIndex, endIndex) {
if (startIndex < 0 || startIndex >= buffer.byteLength ||
endIndex < startIndex || endIndex > buffer.byteLength) {
this.panStrategy_.setCursor(-1, -1);
return;
}
if (startIndex == endIndex) {
endIndex = startIndex + 1;
}
var dataView = new DataView(buffer);
while (startIndex < endIndex) {
var value = dataView.getUint8(startIndex);
value |= cvox.BrailleDisplayManager.CURSOR_DOTS_;
dataView.setUint8(startIndex, value);
startIndex++;
}
this.panStrategy_.setCursor(startIndex, endIndex);
};
/**
......
......@@ -70,7 +70,7 @@ CvoxBrailleDisplayManagerUnitTest.prototype = {
assertEquals(1, this.writtenCells.length);
var a = new Uint8Array(this.writtenCells[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,
// which is a value, are the same because the fakeTranslator generates
// the values of the braille cells based on indices.
......@@ -78,8 +78,8 @@ CvoxBrailleDisplayManagerUnitTest.prototype = {
' Start mismatch: ' + start + ' vs. ' + firstCell);
if (opt_selStart !== undefined) {
for (var i = opt_selStart; i < opt_selEnd; ++i) {
assertEquals(cvox.BrailleDisplayManager.CURSOR_DOTS_,
a[i] & cvox.BrailleDisplayManager.CURSOR_DOTS_,
assertEquals(cvox.BrailleDisplayManager.CURSOR_DOTS,
a[i] & cvox.BrailleDisplayManager.CURSOR_DOTS,
'Missing cursor marker at position ' + i);
}
}
......
......@@ -75,6 +75,11 @@ cvox.PanStrategy = function() {
*/
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 = {
},
/**
* @param {boolean=} opt_showCursor Defaults to true.
* @return {ArrayBuffer} Buffer of the slice of braille cells within the
* bounds of the viewport.
*/
getCurrentBrailleViewportContents: function() {
getCurrentBrailleViewportContents: function(opt_showCursor) {
opt_showCursor = opt_showCursor === undefined ? true : opt_showCursor;
var buf =
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(
this.viewPort_.firstRow * this.displaySize_.columns,
(this.viewPort_.lastRow + 1) * this.displaySize_.columns);
......@@ -252,6 +284,8 @@ cvox.PanStrategy.prototype = {
} else {
// |lastBreak| is at the beginning of a line, so current word is
// bigger than |this.displaySize_.columns| so we shouldn't wrap.
this.maybeSetWrappedCursor_(
index - cellsPadded, wrappedBrailleArray.length);
wrappedBrailleArray.push(view[index - cellsPadded]);
this.wrappedBrailleToText_.push(
fixedBrailleToText[index - cellsPadded]);
......@@ -260,6 +294,8 @@ cvox.PanStrategy.prototype = {
if (view[index - cellsPadded] == 0) {
lastBreak = index;
}
this.maybeSetWrappedCursor_(
index - cellsPadded, wrappedBrailleArray.length);
wrappedBrailleArray.push(view[index - cellsPadded]);
this.wrappedBrailleToText_.push(
fixedBrailleToText[index - cellsPadded]);
......@@ -273,6 +309,29 @@ cvox.PanStrategy.prototype = {
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
* 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