OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * The current selection object. | 8 * The current selection object. |
9 * | 9 * |
10 * @param {FileManager} fileManager FileManager instance. | 10 * @param {FileManager} fileManager FileManager instance. |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 return; | 317 return; |
318 selection.tasks.display(this.taskItems_); | 318 selection.tasks.display(this.taskItems_); |
319 selection.tasks.updateMenuItem(); | 319 selection.tasks.updateMenuItem(); |
320 }.bind(this)); | 320 }.bind(this)); |
321 } else { | 321 } else { |
322 this.taskItems_.hidden = true; | 322 this.taskItems_.hidden = true; |
323 } | 323 } |
324 | 324 |
325 // Update preview panels. | 325 // Update preview panels. |
326 var wasVisible = this.previewPanel_.visible; | 326 var wasVisible = this.previewPanel_.visible; |
327 var thumbnailEntries; | 327 var thumbnailSelection; |
328 if (selection.totalCount == 0) { | 328 if (selection.totalCount != 0) { |
329 thumbnailEntries = [ | 329 thumbnailSelection = selection; |
330 this.fileManager_.getCurrentDirectoryEntry() | |
331 ]; | |
332 } else { | 330 } else { |
333 thumbnailEntries = selection.entries; | 331 thumbnailSelection = { |
| 332 entries: [this.fileManager_.getCurrentDirectoryEntry()] |
| 333 }; |
334 } | 334 } |
335 this.previewPanel_.setSelection(selection); | 335 this.previewPanel_.setSelection(selection); |
336 this.showPreviewThumbnails_(thumbnailEntries); | 336 this.previewPanel_.thumbnails.selection = thumbnailSelection; |
337 | 337 |
338 // Update breadcrums. | 338 // Update breadcrums. |
339 var updateTarget = null; | 339 var updateTarget = null; |
340 var path = this.fileManager_.getCurrentDirectory(); | 340 var path = this.fileManager_.getCurrentDirectory(); |
341 if (selection.totalCount == 1) { | 341 if (selection.totalCount == 1) { |
342 // Shows the breadcrumb list when a file is selected. | 342 // Shows the breadcrumb list when a file is selected. |
343 updateTarget = selection.entries[0].fullPath; | 343 updateTarget = selection.entries[0].fullPath; |
344 } else if (selection.totalCount == 0 && | 344 } else if (selection.totalCount == 0 && |
345 this.previewPanel_.visible) { | 345 this.previewPanel_.visible) { |
346 // Shows the breadcrumb list when no file is selected and the preview | 346 // Shows the breadcrumb list when no file is selected and the preview |
(...skipping 15 matching lines...) Expand all Loading... |
362 // Update context menu. | 362 // Update context menu. |
363 this.fileManager_.updateContextMenuActionItems(null, false); | 363 this.fileManager_.updateContextMenuActionItems(null, false); |
364 | 364 |
365 // Inform tests it's OK to click buttons now. | 365 // Inform tests it's OK to click buttons now. |
366 if (selection.totalCount > 0) { | 366 if (selection.totalCount > 0) { |
367 chrome.test.sendMessage('selection-change-complete'); | 367 chrome.test.sendMessage('selection-change-complete'); |
368 } | 368 } |
369 }; | 369 }; |
370 | 370 |
371 /** | 371 /** |
372 * Renders preview thumbnails in preview panel. | |
373 * | |
374 * @param {Array.<FileEntry>} entries The entries of selected object. | |
375 * @private | |
376 */ | |
377 FileSelectionHandler.prototype.showPreviewThumbnails_ = function(entries) { | |
378 var selection = this.selection; | |
379 var thumbnails = []; | |
380 var thumbnailCount = 0; | |
381 var thumbnailLoaded = -1; | |
382 var forcedShowTimeout = null; | |
383 var thumbnailsHaveZoom = false; | |
384 var self = this; | |
385 | |
386 var showThumbnails = function() { | |
387 // have-zoom class may be updated twice: then timeout exceeds and then | |
388 // then all images loaded. | |
389 if (self.selection == selection) { | |
390 if (thumbnailsHaveZoom) { | |
391 self.previewThumbnails_.classList.add('has-zoom'); | |
392 } else { | |
393 self.previewThumbnails_.classList.remove('has-zoom'); | |
394 } | |
395 } | |
396 | |
397 if (forcedShowTimeout === null) | |
398 return; | |
399 clearTimeout(forcedShowTimeout); | |
400 forcedShowTimeout = null; | |
401 | |
402 // FileSelection could change while images are loading. | |
403 if (self.selection == selection) { | |
404 self.previewThumbnails_.textContent = ''; | |
405 for (var i = 0; i < thumbnails.length; i++) | |
406 self.previewThumbnails_.appendChild(thumbnails[i]); | |
407 } | |
408 }; | |
409 | |
410 var onThumbnailLoaded = function() { | |
411 thumbnailLoaded++; | |
412 if (thumbnailLoaded == thumbnailCount) | |
413 showThumbnails(); | |
414 }; | |
415 | |
416 var thumbnailClickHandler = function() { | |
417 if (selection.tasks) | |
418 selection.tasks.executeDefault(); | |
419 }; | |
420 | |
421 var doc = this.fileManager_.document_; | |
422 for (var i = 0; i < entries.length; i++) { | |
423 var entry = entries[i]; | |
424 | |
425 if (thumbnailCount < FileSelectionHandler.MAX_PREVIEW_THUMBNAIL_COUNT) { | |
426 var box = doc.createElement('div'); | |
427 box.className = 'thumbnail'; | |
428 if (thumbnailCount == 0) { | |
429 var zoomed = doc.createElement('div'); | |
430 zoomed.hidden = true; | |
431 thumbnails.push(zoomed); | |
432 var onFirstThumbnailLoaded = function(img, transform) { | |
433 if (img && self.decorateThumbnailZoom_(zoomed, img, transform)) { | |
434 zoomed.hidden = false; | |
435 thumbnailsHaveZoom = true; | |
436 } | |
437 onThumbnailLoaded(); | |
438 }; | |
439 var thumbnail = this.renderThumbnail_(entry, onFirstThumbnailLoaded); | |
440 zoomed.addEventListener('click', thumbnailClickHandler); | |
441 } else { | |
442 var thumbnail = this.renderThumbnail_(entry, onThumbnailLoaded); | |
443 } | |
444 thumbnailCount++; | |
445 box.appendChild(thumbnail); | |
446 box.style.zIndex = | |
447 FileSelectionHandler.MAX_PREVIEW_THUMBNAIL_COUNT + 1 - i; | |
448 box.addEventListener('click', thumbnailClickHandler); | |
449 | |
450 thumbnails.push(box); | |
451 } | |
452 } | |
453 | |
454 forcedShowTimeout = setTimeout(showThumbnails, | |
455 FileManager.THUMBNAIL_SHOW_DELAY); | |
456 onThumbnailLoaded(); | |
457 }; | |
458 | |
459 /** | |
460 * Renders a thumbnail for the buttom panel. | |
461 * | |
462 * @param {Entry} entry Entry to render for. | |
463 * @param {function} callback Called when image loaded. | |
464 * @return {HTMLDivElement} Created element. | |
465 * @private | |
466 */ | |
467 FileSelectionHandler.prototype.renderThumbnail_ = function(entry, callback) { | |
468 var thumbnail = this.fileManager_.document_.createElement('div'); | |
469 FileGrid.decorateThumbnailBox(thumbnail, | |
470 entry, | |
471 this.fileManager_.metadataCache_, | |
472 ThumbnailLoader.FillMode.FILL, | |
473 FileGrid.ThumbnailQuality.LOW, | |
474 callback); | |
475 return thumbnail; | |
476 }; | |
477 | |
478 /** | |
479 * Updates the breadcrumbs in the preview panel. | 372 * Updates the breadcrumbs in the preview panel. |
480 * | 373 * |
481 * @param {?string} path Path to be shown in the breadcrumbs list | 374 * @param {?string} path Path to be shown in the breadcrumbs list |
482 * @private | 375 * @private |
483 */ | 376 */ |
484 FileSelectionHandler.prototype.updatePreviewPanelBreadcrumbs_ = function(path) { | 377 FileSelectionHandler.prototype.updatePreviewPanelBreadcrumbs_ = function(path) { |
485 if (!path) | 378 if (!path) |
486 this.searchBreadcrumbs_.hide(); | 379 this.searchBreadcrumbs_.hide(); |
487 else | 380 else |
488 this.searchBreadcrumbs_.show(PathUtil.getRootPath(path), path); | 381 this.searchBreadcrumbs_.show(PathUtil.getRootPath(path), path); |
(...skipping 12 matching lines...) Expand all Loading... |
501 this.searchBreadcrumbs_.hide(); | 394 this.searchBreadcrumbs_.hide(); |
502 return; | 395 return; |
503 } | 396 } |
504 | 397 |
505 var entry = this.fileManager_.getFileList().item( | 398 var entry = this.fileManager_.getFileList().item( |
506 selectedIndexes[0]); | 399 selectedIndexes[0]); |
507 this.searchBreadcrumbs_.show( | 400 this.searchBreadcrumbs_.show( |
508 PathUtil.getRootPath(entry.fullPath), | 401 PathUtil.getRootPath(entry.fullPath), |
509 entry.fullPath); | 402 entry.fullPath); |
510 }; | 403 }; |
511 | |
512 /** | |
513 * Creates enlarged image for a bottom pannel thumbnail. | |
514 * Image's assumed to be just loaded and not inserted into the DOM. | |
515 * | |
516 * @param {HTMLElement} largeImageBox DIV element to decorate. | |
517 * @param {HTMLElement} img Loaded image. | |
518 * @param {Object} transform Image transformation description. | |
519 * @return {boolean} True if zoomed image is present. | |
520 * @private | |
521 */ | |
522 FileSelectionHandler.prototype.decorateThumbnailZoom_ = function( | |
523 largeImageBox, img, transform) { | |
524 var width = img.width; | |
525 var height = img.height; | |
526 var THUMBNAIL_SIZE = 35; | |
527 if (width < THUMBNAIL_SIZE * 2 && height < THUMBNAIL_SIZE * 2) | |
528 return false; | |
529 | |
530 var scale = Math.min(1, | |
531 FileSelectionHandler.IMAGE_HOVER_PREVIEW_SIZE / Math.max(width, height)); | |
532 | |
533 var imageWidth = Math.round(width * scale); | |
534 var imageHeight = Math.round(height * scale); | |
535 | |
536 var largeImage = this.fileManager_.document_.createElement('img'); | |
537 if (scale < 0.3) { | |
538 // Scaling large images kills animation. Downscale it in advance. | |
539 | |
540 // Canvas scales images with liner interpolation. Make a larger | |
541 // image (but small enough to not kill animation) and let IMG | |
542 // scale it smoothly. | |
543 var INTERMEDIATE_SCALE = 3; | |
544 var canvas = this.fileManager_.document_.createElement('canvas'); | |
545 canvas.width = imageWidth * INTERMEDIATE_SCALE; | |
546 canvas.height = imageHeight * INTERMEDIATE_SCALE; | |
547 var ctx = canvas.getContext('2d'); | |
548 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | |
549 // Using bigger than default compression reduces image size by | |
550 // several times. Quality degradation compensated by greater resolution. | |
551 largeImage.src = canvas.toDataURL('image/jpeg', 0.6); | |
552 } else { | |
553 largeImage.src = img.src; | |
554 } | |
555 largeImageBox.className = 'popup'; | |
556 | |
557 var boxWidth = Math.max(THUMBNAIL_SIZE, imageWidth); | |
558 var boxHeight = Math.max(THUMBNAIL_SIZE, imageHeight); | |
559 | |
560 if (transform && transform.rotate90 % 2 == 1) { | |
561 var t = boxWidth; | |
562 boxWidth = boxHeight; | |
563 boxHeight = t; | |
564 } | |
565 | |
566 var style = largeImageBox.style; | |
567 style.width = boxWidth + 'px'; | |
568 style.height = boxHeight + 'px'; | |
569 style.top = (-boxHeight + THUMBNAIL_SIZE) + 'px'; | |
570 | |
571 var style = largeImage.style; | |
572 style.width = imageWidth + 'px'; | |
573 style.height = imageHeight + 'px'; | |
574 style.left = (boxWidth - imageWidth) / 2 + 'px'; | |
575 style.top = (boxHeight - imageHeight) / 2 + 'px'; | |
576 style.position = 'relative'; | |
577 | |
578 util.applyTransform(largeImage, transform); | |
579 | |
580 largeImageBox.appendChild(largeImage); | |
581 largeImageBox.style.zIndex = 1000; | |
582 return true; | |
583 }; | |
OLD | NEW |