Merge pull request #7635 from Snuffleupagus/CursorTools

Unify handling of various cursor tools, e.g. the current Hand Tool and a possible future Zoom Tool, in a new `PDFCursorTools` module
This commit is contained in:
Jonas Jenwald 2017-05-22 10:36:52 +02:00 committed by GitHub
commit b4c35857ff
14 changed files with 244 additions and 149 deletions

View File

@ -27,11 +27,19 @@
"default": 0
},
"enableHandToolOnLoad": {
"title": "Activate Hand tool by default",
"description": "Whether to activate the hand tool by default.",
"type": "boolean",
"default": false
},
"cursorToolOnLoad": {
"title": "Cursor tool on load",
"description": "The cursor tool that is enabled upon load.\n 0 = Text selection tool.\n 1 = Hand tool.",
"type": "integer",
"enum": [
0,
1
],
"default": 0
},
"enableWebGL": {
"title": "Enable WebGL",
"description": "Whether to enable WebGL.",

View File

@ -60,10 +60,10 @@ page_rotate_ccw.title=Rotate Counterclockwise
page_rotate_ccw.label=Rotate Counterclockwise
page_rotate_ccw_label=Rotate Counterclockwise
hand_tool_enable.title=Enable hand tool
hand_tool_enable_label=Enable hand tool
hand_tool_disable.title=Disable hand tool
hand_tool_disable_label=Disable hand tool
cursor_text_select_tool.title=Enable Text Selection Tool
cursor_text_select_tool_label=Text Selection Tool
cursor_hand_tool.title=Enable Hand Tool
cursor_hand_tool_label=Hand Tool
# Document properties dialog box
document_properties.title=Document Properties…

View File

@ -60,10 +60,10 @@ page_rotate_ccw.title=Linksom draaien
page_rotate_ccw.label=Linksom draaien
page_rotate_ccw_label=Linksom draaien
hand_tool_enable.title=Handhulpmiddel inschakelen
hand_tool_enable_label=Handhulpmiddel inschakelen
hand_tool_disable.title=Handhulpmiddel uitschakelen
hand_tool_disable_label=Handhulpmiddel uitschakelen
cursor_text_select_tool.title=Tekstselectiehulpmiddel inschakelen
cursor_text_select_tool_label=Tekstselectiehulpmiddel
cursor_hand_tool.title=Handhulpmiddel inschakelen
cursor_hand_tool_label=Handhulpmiddel
# Document properties dialog box
document_properties.title=Documenteigenschappen…

View File

@ -60,10 +60,10 @@ page_rotate_ccw.title=Rotera moturs
page_rotate_ccw.label=Rotera moturs
page_rotate_ccw_label=Rotera moturs
hand_tool_enable.title=Aktivera handverktyg
hand_tool_enable_label=Aktivera handverktyg
hand_tool_disable.title=Inaktivera handverktyg
hand_tool_disable_label=Inaktivera handverktyg
cursor_text_select_tool.title=Aktivera Textmarkeringsverktyg
cursor_text_select_tool_label=Textmarkeringsverktyg
cursor_hand_tool.title=Aktivera handverktyg
cursor_hand_tool_label=Handverktyg
# Document properties dialog box
document_properties.title=Dokumentegenskaper…

View File

@ -24,13 +24,11 @@ import {
MissingPDFException, OPS, PDFJS, shadow, UnexpectedResponseException,
UNSUPPORTED_FEATURES, version,
} from './pdfjs';
import {
PDFRenderingQueue, RenderingStates
} from './pdf_rendering_queue';
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
import { PDFSidebar, SidebarView } from './pdf_sidebar';
import { PDFViewer, PresentationModeState } from './pdf_viewer';
import { getGlobalEventBus } from './dom_events';
import { HandTool } from './hand_tool';
import { OverlayManager } from './overlay_manager';
import { PasswordPrompt } from './password_prompt';
import { PDFAttachmentViewer } from './pdf_attachment_viewer';
@ -115,6 +113,8 @@ var PDFViewerApplication = {
pdfOutlineViewer: null,
/** @type {PDFAttachmentViewer} */
pdfAttachmentViewer: null,
/** @type {PDFCursorTools} */
pdfCursorTools: null,
/** @type {ViewHistory} */
store: null,
/** @type {DownloadManager} */
@ -337,15 +337,15 @@ var PDFViewerApplication = {
this.overlayManager = OverlayManager;
this.handTool = new HandTool({
this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties);
this.pdfCursorTools = new PDFCursorTools({
container,
eventBus,
preferences: this.preferences,
});
this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties);
this.toolbar = new Toolbar(appConfig.toolbar, container, eventBus);
this.secondaryToolbar =
@ -2119,11 +2119,13 @@ function webViewerKeyDown(evt) {
}
break;
case 72: // 'h'
if (!isViewerInPresentationMode) {
PDFViewerApplication.handTool.toggle();
}
case 83: // 's'
PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.SELECT);
break;
case 72: // 'h'
PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.HAND);
break;
case 82: // 'r'
PDFViewerApplication.rotatePages(90);
break;

View File

@ -3,6 +3,7 @@
"defaultZoomValue": "",
"sidebarViewOnLoad": 0,
"enableHandToolOnLoad": false,
"cursorToolOnLoad": 0,
"enableWebGL": false,
"pdfBugEnabled": false,
"disableRange": false,

View File

@ -1,93 +0,0 @@
/* Copyright 2013 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GrabToPan } from './grab_to_pan';
import { localized } from './ui_utils';
/**
* @typedef {Object} HandToolOptions
* @property {HTMLDivElement} container - The document container.
* @property {EventBus} eventBus - The application event bus.
* @property {BasePreferences} preferences - Object for reading/writing
* persistent settings.
*/
class HandTool {
/**
* @param {HandToolOptions} options
*/
constructor({ container, eventBus, preferences, }) {
this.container = container;
this.eventBus = eventBus;
this.wasActive = false;
this.handTool = new GrabToPan({
element: this.container,
onActiveChanged: (isActive) => {
this.eventBus.dispatch('handtoolchanged', { isActive, });
},
});
this.eventBus.on('togglehandtool', this.toggle.bind(this));
let enableOnLoad = preferences.get('enableHandToolOnLoad');
Promise.all([localized, enableOnLoad]).then((values) => {
if (values[1] === true) {
this.handTool.activate();
}
}).catch(function(reason) {});
this.eventBus.on('presentationmodechanged', (evt) => {
if (evt.switchInProgress) {
return;
}
if (evt.active) {
this.enterPresentationMode();
} else {
this.exitPresentationMode();
}
});
}
/**
* @return {boolean}
*/
get isActive() {
return !!this.handTool.active;
}
toggle() {
this.handTool.toggle();
}
enterPresentationMode() {
if (this.isActive) {
this.wasActive = true;
this.handTool.deactivate();
}
}
exitPresentationMode() {
if (this.wasActive) {
this.wasActive = false;
this.handTool.activate();
}
}
}
export {
HandTool,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

163
web/pdf_cursor_tools.js Normal file
View File

@ -0,0 +1,163 @@
/* Copyright 2017 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GrabToPan } from './grab_to_pan';
const CursorTool = {
SELECT: 0, // The default value.
HAND: 1,
ZOOM: 2,
};
/**
* @typedef {Object} PDFCursorToolsOptions
* @property {HTMLDivElement} container - The document container.
* @property {EventBus} eventBus - The application event bus.
* @property {BasePreferences} preferences - Object for reading/writing
* persistent settings.
*/
class PDFCursorTools {
/**
* @param {PDFCursorToolsOptions} options
*/
constructor({ container, eventBus, preferences, }) {
this.container = container;
this.eventBus = eventBus;
this.active = CursorTool.SELECT;
this.activeBeforePresentationMode = null;
this.handTool = new GrabToPan({
element: this.container,
});
this._addEventListeners();
Promise.all([
preferences.get('cursorToolOnLoad'),
preferences.get('enableHandToolOnLoad')
]).then(([cursorToolPref, handToolPref]) => {
// If the 'cursorToolOnLoad' preference has not been set to a non-default
// value, attempt to convert the old 'enableHandToolOnLoad' preference.
// TODO: Remove this conversion after a suitable number of releases.
if (handToolPref === true) {
preferences.set('enableHandToolOnLoad', false);
if (cursorToolPref === CursorTool.SELECT) {
cursorToolPref = CursorTool.HAND;
preferences.set('cursorToolOnLoad', cursorToolPref).catch(() => { });
}
}
this.switchTool(cursorToolPref);
}).catch(() => { });
}
/**
* @returns {number} One of the values in {CursorTool}.
*/
get activeTool() {
return this.active;
}
/**
* NOTE: This method is ignored while Presentation Mode is active.
* @param {number} tool - The cursor mode that should be switched to,
* must be one of the values in {CursorTool}.
*/
switchTool(tool) {
if (this.activeBeforePresentationMode !== null) {
return; // Cursor tools cannot be used in Presentation Mode.
}
if (tool === this.active) {
return; // The requested tool is already active.
}
let disableActiveTool = () => {
switch (this.active) {
case CursorTool.SELECT:
break;
case CursorTool.HAND:
this.handTool.deactivate();
break;
case CursorTool.ZOOM:
/* falls through */
}
};
switch (tool) { // Enable the new cursor tool.
case CursorTool.SELECT:
disableActiveTool();
break;
case CursorTool.HAND:
disableActiveTool();
this.handTool.activate();
break;
case CursorTool.ZOOM:
/* falls through */
default:
console.error(`switchTool: "${tool}" is an unsupported value.`);
return;
}
// Update the active tool *after* it has been validated above,
// in order to prevent setting it to an invalid state.
this.active = tool;
this._dispatchEvent();
}
/**
* @private
*/
_dispatchEvent() {
this.eventBus.dispatch('cursortoolchanged', {
source: this,
tool: this.active,
});
}
/**
* @private
*/
_addEventListeners() {
this.eventBus.on('switchcursortool', (evt) => {
this.switchTool(evt.tool);
});
this.eventBus.on('presentationmodechanged', (evt) => {
if (evt.switchInProgress) {
return;
}
let previouslyActive;
if (evt.active) {
previouslyActive = this.active;
this.switchTool(CursorTool.SELECT);
this.activeBeforePresentationMode = previouslyActive;
} else {
previouslyActive = this.activeBeforePresentationMode;
this.activeBeforePresentationMode = null;
this.switchTool(previouslyActive);
}
});
}
}
export {
CursorTool,
PDFCursorTools,
};

View File

@ -13,7 +13,8 @@
* limitations under the License.
*/
import { mozL10n, SCROLLBAR_PADDING } from './ui_utils';
import { CursorTool } from './pdf_cursor_tools';
import { SCROLLBAR_PADDING } from './ui_utils';
/**
* @typedef {Object} SecondaryToolbarOptions
@ -39,7 +40,9 @@ import { mozL10n, SCROLLBAR_PADDING } from './ui_utils';
* clockwise.
* @property {HTMLButtonElement} pageRotateCcwButton - Button to rotate the
* pages counterclockwise.
* @property {HTMLButtonElement} toggleHandToolButton - Button to toggle the
* @property {HTMLButtonElement} cursorSelectToolButton - Button to enable the
* select tool.
* @property {HTMLButtonElement} cursorHandToolButton - Button to enable the
* hand tool.
* @property {HTMLButtonElement} documentPropertiesButton - Button for opening
* the document properties dialog.
@ -68,8 +71,10 @@ class SecondaryToolbar {
close: false },
{ element: options.pageRotateCcwButton, eventName: 'rotateccw',
close: false },
{ element: options.toggleHandToolButton, eventName: 'togglehandtool',
close: true },
{ element: options.cursorSelectToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.SELECT, }, close: true },
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true },
{ element: options.documentPropertiesButton,
eventName: 'documentproperties', close: true }
];
@ -89,9 +94,9 @@ class SecondaryToolbar {
this.reset();
// Bind the event listeners for click and hand tool actions.
// Bind the event listeners for click and cursor tool actions.
this._bindClickListeners();
this._bindHandToolListener(options.toggleHandToolButton);
this._bindCursorToolsListener(options);
// Bind the event listener for adjusting the 'max-height' of the toolbar.
this.eventBus.on('resize', this._setMaxHeight.bind(this));
@ -133,11 +138,15 @@ class SecondaryToolbar {
// All items within the secondary toolbar.
for (let button in this.buttons) {
let { element, eventName, close, } = this.buttons[button];
let { element, eventName, close, eventDetails, } = this.buttons[button];
element.addEventListener('click', (evt) => {
if (eventName !== null) {
this.eventBus.dispatch(eventName, { source: this, });
let details = { source: this, };
for (let property in eventDetails) {
details[property] = eventDetails[property];
}
this.eventBus.dispatch(eventName, details);
}
if (close) {
this.close();
@ -146,25 +155,18 @@ class SecondaryToolbar {
}
}
_bindHandToolListener(toggleHandToolButton) {
let isHandToolActive = false;
_bindCursorToolsListener(buttons) {
this.eventBus.on('cursortoolchanged', function(evt) {
buttons.cursorSelectToolButton.classList.remove('toggled');
buttons.cursorHandToolButton.classList.remove('toggled');
this.eventBus.on('handtoolchanged', function(evt) {
if (isHandToolActive === evt.isActive) {
return;
}
isHandToolActive = evt.isActive;
if (isHandToolActive) {
toggleHandToolButton.title =
mozL10n.get('hand_tool_disable.title', null, 'Disable hand tool');
toggleHandToolButton.firstElementChild.textContent =
mozL10n.get('hand_tool_disable_label', null, 'Disable hand tool');
} else {
toggleHandToolButton.title =
mozL10n.get('hand_tool_enable.title', null, 'Enable hand tool');
toggleHandToolButton.firstElementChild.textContent =
mozL10n.get('hand_tool_enable_label', null, 'Enable hand tool');
switch (evt.tool) {
case CursorTool.SELECT:
buttons.cursorSelectToolButton.classList.add('toggled');
break;
case CursorTool.HAND:
buttons.cursorHandToolButton.classList.add('toggled');
break;
}
});
}

View File

@ -1010,6 +1010,10 @@ html[dir="rtl"] .secondaryToolbarButton > span {
content: url(images/secondaryToolbarButton-rotateCw.png);
}
.secondaryToolbarButton.selectTool::before {
content: url(images/secondaryToolbarButton-selectTool.png);
}
.secondaryToolbarButton.handTool::before {
content: url(images/secondaryToolbarButton-handTool.png);
}
@ -1735,6 +1739,10 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
content: url(images/secondaryToolbarButton-rotateCw@2x.png);
}
.secondaryToolbarButton.selectTool::before {
content: url(images/secondaryToolbarButton-selectTool@2x.png);
}
.secondaryToolbarButton.handTool::before {
content: url(images/secondaryToolbarButton-handTool@2x.png);
}

View File

@ -166,13 +166,16 @@ See https://github.com/adobe-type-tools/cmap-resources
<div class="horizontalToolbarSeparator"></div>
<button id="toggleHandTool" class="secondaryToolbarButton handTool" title="Enable hand tool" tabindex="60" data-l10n-id="hand_tool_enable">
<span data-l10n-id="hand_tool_enable_label">Enable hand tool</span>
<button id="cursorSelectTool" class="secondaryToolbarButton selectTool toggled" title="Enable Text Selection Tool" tabindex="60" data-l10n-id="cursor_text_select_tool">
<span data-l10n-id="cursor_text_select_tool_label">Text Selection Tool</span>
</button>
<button id="cursorHandTool" class="secondaryToolbarButton handTool" title="Enable Hand Tool" tabindex="61" data-l10n-id="cursor_hand_tool">
<span data-l10n-id="cursor_hand_tool_label">Hand Tool</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="61" data-l10n-id="document_properties">
<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="62" data-l10n-id="document_properties">
<span data-l10n-id="document_properties_label">Document Properties…</span>
</button>
</div>

View File

@ -93,7 +93,8 @@ function getViewerConfiguration() {
lastPageButton: document.getElementById('lastPage'),
pageRotateCwButton: document.getElementById('pageRotateCw'),
pageRotateCcwButton: document.getElementById('pageRotateCcw'),
toggleHandToolButton: document.getElementById('toggleHandTool'),
cursorSelectToolButton: document.getElementById('cursorSelectTool'),
cursorHandToolButton: document.getElementById('cursorHandTool'),
documentPropertiesButton: document.getElementById('documentProperties'),
},
fullscreen: {