Input type filters (#806)
* Add options for scanning input types * Move buttons in layout, refactor CSS * Add options for input types * Use input type filters * Add _getMatchingInputGroupFromEvent * Use input filters for touch events
This commit is contained in:
parent
18634dca1a
commit
a1729eb9ae
@ -133,10 +133,7 @@ html:root:not([data-options-general-result-output-mode=merge]) #dict-main-group
|
|||||||
}
|
}
|
||||||
.scan-input-table {
|
.scan-input-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
margin-bottom: 8px;
|
||||||
.scan-input-list:not(:empty)+#scan-input-add {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
}
|
}
|
||||||
.scan-input-index-cell {
|
.scan-input-index-cell {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -153,6 +150,7 @@ html:root:not([data-options-general-result-output-mode=merge]) #dict-main-group
|
|||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-top-left-radius: 4px;
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -174,22 +172,46 @@ html:root:not([data-options-general-result-output-mode=merge]) #dict-main-group
|
|||||||
.scan-input-input-cell {
|
.scan-input-input-cell {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.scan-input-input-cell>input {
|
.scan-input-input-cell-inner {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.scan-input-input-cell-inner .form-control,
|
||||||
|
.scan-input-input-cell-inner button {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
.scan-input-mouse-button-cell>button {
|
.scan-input-input-cell-inner button {
|
||||||
border-radius: 0;
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
.scan-input-input-cell-inner button>span {
|
||||||
|
width: 20px;
|
||||||
}
|
}
|
||||||
.scan-input-remove-button-cell>button {
|
.scan-input-remove-button-cell>button {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
}
|
}
|
||||||
.scan-input:nth-child(n+2) .scan-input-index {
|
.scan-input tr:last-of-type .scan-input-input-cell-inner button:last-of-type,
|
||||||
border-top-left-radius: 0;
|
.scan-input tr:last-of-type .scan-input-input-cell-inner .form-control:last-of-type {
|
||||||
}
|
|
||||||
.scan-input:last-child tr:last-of-type .scan-input-mouse-button-cell>button {
|
|
||||||
border-bottom-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
||||||
}
|
}
|
||||||
|
.scan-input-type-list {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.scan-input-type {
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.scan-input-type+.scan-input-type {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
.scan-input-type>input[type=checkbox] {
|
||||||
|
margin: 0 0.375em 0 0;
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.scan-input-type>span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
.generic-input-list {
|
.generic-input-list {
|
||||||
counter-reset: generic-input-id;
|
counter-reset: generic-input-id;
|
||||||
|
@ -341,13 +341,28 @@
|
|||||||
"default": [
|
"default": [
|
||||||
{
|
{
|
||||||
"include": "shift",
|
"include": "shift",
|
||||||
"exclude": ""
|
"exclude": "",
|
||||||
|
"types": {
|
||||||
|
"mouse": true,
|
||||||
|
"touch": false,
|
||||||
|
"pen": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "",
|
||||||
|
"exclude": "",
|
||||||
|
"types": {
|
||||||
|
"mouse": false,
|
||||||
|
"touch": true,
|
||||||
|
"pen": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"items": {
|
"items": {
|
||||||
"required": [
|
"required": [
|
||||||
"include",
|
"include",
|
||||||
"exclude"
|
"exclude",
|
||||||
|
"types"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"include": {
|
"include": {
|
||||||
@ -357,6 +372,28 @@
|
|||||||
"exclude": {
|
"exclude": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": ""
|
"default": ""
|
||||||
|
},
|
||||||
|
"types": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"mouse",
|
||||||
|
"touch",
|
||||||
|
"pen"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"mouse": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"touch": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"pen": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,7 +491,7 @@ class OptionsUtil {
|
|||||||
profileOptions.general.usePopupWindow = false;
|
profileOptions.general.usePopupWindow = false;
|
||||||
profileOptions.scanning.hideDelay = 0;
|
profileOptions.scanning.hideDelay = 0;
|
||||||
|
|
||||||
const {modifier, middleMouse} = profileOptions.scanning;
|
const {modifier, middleMouse, touchInputEnabled} = profileOptions.scanning;
|
||||||
const scanningInputs = [];
|
const scanningInputs = [];
|
||||||
let modifierInput = '';
|
let modifierInput = '';
|
||||||
switch (modifier) {
|
switch (modifier) {
|
||||||
@ -507,12 +507,21 @@ class OptionsUtil {
|
|||||||
}
|
}
|
||||||
scanningInputs.push({
|
scanningInputs.push({
|
||||||
include: modifierInput,
|
include: modifierInput,
|
||||||
exclude: ''
|
exclude: '',
|
||||||
|
types: {mouse: true, touch: false, pen: false}
|
||||||
});
|
});
|
||||||
if (middleMouse) {
|
if (middleMouse) {
|
||||||
scanningInputs.push({
|
scanningInputs.push({
|
||||||
include: 'mouse2',
|
include: 'mouse2',
|
||||||
exclude: ''
|
exclude: '',
|
||||||
|
types: {mouse: true, touch: false, pen: false}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (touchInputEnabled) {
|
||||||
|
scanningInputs.push({
|
||||||
|
include: '',
|
||||||
|
exclude: '',
|
||||||
|
types: {mouse: false, touch: true, pen: true}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
profileOptions.scanning.inputs = scanningInputs;
|
profileOptions.scanning.inputs = scanningInputs;
|
||||||
|
@ -142,6 +142,11 @@ class ScanInputField {
|
|||||||
this._eventListeners.on(this._includeInputField, 'change', this._onIncludeValueChange.bind(this));
|
this._eventListeners.on(this._includeInputField, 'change', this._onIncludeValueChange.bind(this));
|
||||||
this._eventListeners.on(this._excludeInputField, 'change', this._onExcludeValueChange.bind(this));
|
this._eventListeners.on(this._excludeInputField, 'change', this._onExcludeValueChange.bind(this));
|
||||||
this._eventListeners.addEventListener(removeButton, 'click', this._onRemoveClick.bind(this));
|
this._eventListeners.addEventListener(removeButton, 'click', this._onRemoveClick.bind(this));
|
||||||
|
|
||||||
|
for (const typeCheckbox of node.querySelectorAll('.scan-input-type-checkbox')) {
|
||||||
|
const {type} = typeCheckbox.dataset;
|
||||||
|
typeCheckbox.dataset.setting = `scanning.inputs[${this._index}].types.${type}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
|
@ -436,16 +436,31 @@
|
|||||||
<template id="scan-input-template"><div class="scan-input">
|
<template id="scan-input-template"><div class="scan-input">
|
||||||
<table class="scan-input-table"><tbody>
|
<table class="scan-input-table"><tbody>
|
||||||
<tr class="scan-input-include">
|
<tr class="scan-input-include">
|
||||||
<td class="scan-input-index-cell" rowspan="2"><div class="scan-input-index"></div></td>
|
<td class="scan-input-index-cell" rowspan="3"><div class="scan-input-index"></div></td>
|
||||||
<td class="scan-input-prefix-cell"><div class="scan-input-prefix">Include</div></td>
|
<td class="scan-input-prefix-cell"><div class="scan-input-prefix">Include</div></td>
|
||||||
<td class="scan-input-input-cell"><input type="text" class="form-control scan-input-field" placeholder="No inputs"></td>
|
<td class="scan-input-input-cell"><div class="scan-input-input-cell-inner">
|
||||||
<td class="scan-input-mouse-button-cell"><button class="btn btn-default mouse-button" title="Mouse button"><span class="mouse-button-icon"></span></button></td>
|
<input type="text" class="form-control scan-input-field" placeholder="No inputs">
|
||||||
|
<button class="btn btn-default mouse-button" title="Mouse button"><span class="mouse-button-icon"></span></button>
|
||||||
|
</div></td>
|
||||||
<td class="scan-input-remove-button-cell"><button class="btn btn-danger scan-input-remove" title="Remove"><span class="glyphicon glyphicon-remove"></span></button></td>
|
<td class="scan-input-remove-button-cell"><button class="btn btn-danger scan-input-remove" title="Remove"><span class="glyphicon glyphicon-remove"></span></button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="scan-input-exclude">
|
<tr class="scan-input-exclude">
|
||||||
<td class="scan-input-prefix-cell"><div class="scan-input-prefix">Exclude</div></td>
|
<td class="scan-input-prefix-cell"><div class="scan-input-prefix">Exclude</div></td>
|
||||||
<td class="scan-input-input-cell"><input type="text" class="form-control scan-input-field" placeholder="No inputs"></td>
|
<td class="scan-input-input-cell"><div class="scan-input-input-cell-inner">
|
||||||
<td class="scan-input-mouse-button-cell"><button class="btn btn-default mouse-button" title="Mouse button"><span class="mouse-button-icon"></span></button></td>
|
<input type="text" class="form-control scan-input-field" placeholder="No inputs">
|
||||||
|
<button class="btn btn-default mouse-button" title="Mouse button"><span class="mouse-button-icon"></span></button>
|
||||||
|
</div></td>
|
||||||
|
<td class="scan-input-empty-cell"></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="scan-input-types">
|
||||||
|
<td class="scan-input-prefix-cell"><div class="scan-input-prefix">Types</div></td>
|
||||||
|
<td class="scan-input-input-cell"><div class="scan-input-input-cell-inner">
|
||||||
|
<div class="form-control scan-input-type-list">
|
||||||
|
<label class="scan-input-type"><input type="checkbox" class="scan-input-type-checkbox" data-type="mouse"><span>Mouse</span></label>
|
||||||
|
<label class="scan-input-type"><input type="checkbox" class="scan-input-type-checkbox" data-type="touch"><span>Touch</span></label>
|
||||||
|
<label class="scan-input-type"><input type="checkbox" class="scan-input-type-checkbox" data-type="pen"><span>Pen</span></label>
|
||||||
|
</div>
|
||||||
|
</div></td>
|
||||||
<td class="scan-input-empty-cell"></td>
|
<td class="scan-input-empty-cell"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
|
@ -95,9 +95,10 @@ class TextScanner extends EventDispatcher {
|
|||||||
|
|
||||||
setOptions({inputs, deepContentScan, selectText, delay, touchInputEnabled, scanLength, sentenceExtent, layoutAwareScan}) {
|
setOptions({inputs, deepContentScan, selectText, delay, touchInputEnabled, scanLength, sentenceExtent, layoutAwareScan}) {
|
||||||
if (Array.isArray(inputs)) {
|
if (Array.isArray(inputs)) {
|
||||||
this._inputs = inputs.map(({include, exclude}) => ({
|
this._inputs = inputs.map(({include, exclude, types}) => ({
|
||||||
include: this._getInputArray(include),
|
include: this._getInputArray(include),
|
||||||
exclude: this._getInputArray(exclude)
|
exclude: this._getInputArray(exclude),
|
||||||
|
types: this._getInputTypeSet(types)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (typeof deepContentScan === 'boolean') {
|
if (typeof deepContentScan === 'boolean') {
|
||||||
@ -241,10 +242,7 @@ class TextScanner extends EventDispatcher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const modifiers = DocumentUtil.getActiveModifiersAndButtons(e);
|
const inputInfo = this._getMatchingInputGroupFromEvent(e, 'mouse');
|
||||||
this.trigger('activeModifiersChanged', {modifiers});
|
|
||||||
|
|
||||||
const inputInfo = this._getMatchingInputGroup(modifiers);
|
|
||||||
if (inputInfo === null) { return; }
|
if (inputInfo === null) { return; }
|
||||||
|
|
||||||
const {index, empty} = inputInfo;
|
const {index, empty} = inputInfo;
|
||||||
@ -313,7 +311,7 @@ class TextScanner extends EventDispatcher {
|
|||||||
|
|
||||||
this._primaryTouchIdentifier = primaryTouch.identifier;
|
this._primaryTouchIdentifier = primaryTouch.identifier;
|
||||||
|
|
||||||
this._searchAtFromTouchStart(primaryTouch.clientX, primaryTouch.clientY);
|
this._searchAtFromTouchStart(e, primaryTouch.clientX, primaryTouch.clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onTouchEnd(e) {
|
_onTouchEnd(e) {
|
||||||
@ -345,7 +343,11 @@ class TextScanner extends EventDispatcher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._searchAt(primaryTouch.clientX, primaryTouch.clientY, {cause: 'touchMove', index: -1, empty: false});
|
const inputInfo = this._getMatchingInputGroupFromEvent(e, 'touch');
|
||||||
|
if (inputInfo === null) { return; }
|
||||||
|
|
||||||
|
const {index, empty} = inputInfo;
|
||||||
|
this._searchAt(primaryTouch.clientX, primaryTouch.clientY, {cause: 'touchMove', index, empty});
|
||||||
|
|
||||||
e.preventDefault(); // Disable scroll
|
e.preventDefault(); // Disable scroll
|
||||||
}
|
}
|
||||||
@ -496,12 +498,16 @@ class TextScanner extends EventDispatcher {
|
|||||||
await this._searchAt(x, y, {cause: 'mouse', index: inputIndex, empty: inputEmpty});
|
await this._searchAt(x, y, {cause: 'mouse', index: inputIndex, empty: inputEmpty});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _searchAtFromTouchStart(x, y) {
|
async _searchAtFromTouchStart(e, x, y) {
|
||||||
if (this._pendingLookup) { return; }
|
if (this._pendingLookup) { return; }
|
||||||
|
|
||||||
|
const inputInfo = this._getMatchingInputGroupFromEvent(e, 'touch');
|
||||||
|
if (inputInfo === null) { return; }
|
||||||
|
|
||||||
|
const {index, empty} = inputInfo;
|
||||||
const textSourceCurrentPrevious = this._textSourceCurrent !== null ? this._textSourceCurrent.clone() : null;
|
const textSourceCurrentPrevious = this._textSourceCurrent !== null ? this._textSourceCurrent.clone() : null;
|
||||||
|
|
||||||
await this._searchAt(x, y, {cause: 'touchStart', index: -1, empty: false});
|
await this._searchAt(x, y, {cause: 'touchStart', index, empty});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this._textSourceCurrent !== null &&
|
this._textSourceCurrent !== null &&
|
||||||
@ -513,11 +519,18 @@ class TextScanner extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getMatchingInputGroup(modifiers) {
|
_getMatchingInputGroupFromEvent(event, type) {
|
||||||
|
const modifiers = DocumentUtil.getActiveModifiersAndButtons(event);
|
||||||
|
this.trigger('activeModifiersChanged', {modifiers});
|
||||||
|
return this._getMatchingInputGroup(modifiers, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getMatchingInputGroup(modifiers, type) {
|
||||||
let fallback = null;
|
let fallback = null;
|
||||||
for (let i = 0, ii = this._inputs.length; i < ii; ++i) {
|
for (let i = 0, ii = this._inputs.length; i < ii; ++i) {
|
||||||
const input = this._inputs[i];
|
const input = this._inputs[i];
|
||||||
const {include, exclude} = input;
|
const {include, exclude, types} = input;
|
||||||
|
if (!types.has(type)) { continue; }
|
||||||
if (this._setHasAll(modifiers, include) && (exclude.length === 0 || !this._setHasAll(modifiers, exclude))) {
|
if (this._setHasAll(modifiers, include) && (exclude.length === 0 || !this._setHasAll(modifiers, exclude))) {
|
||||||
if (include.length > 0) {
|
if (include.length > 0) {
|
||||||
return {index: i, empty: false, input};
|
return {index: i, empty: false, input};
|
||||||
@ -545,4 +558,12 @@ class TextScanner extends EventDispatcher {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getInputTypeSet({mouse, touch, pen}) {
|
||||||
|
const set = new Set();
|
||||||
|
if (mouse) { set.add('mouse'); }
|
||||||
|
if (touch) { set.add('touch'); }
|
||||||
|
if (pen) { set.add('pen'); }
|
||||||
|
return set;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user