Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: chrome/browser/cocoa/tabpose_window.mm

Issue 3389010: Mac: Add a few more keyboard shortcuts to tabpose. (Closed)
Patch Set: comments Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #import "chrome/browser/cocoa/tabpose_window.h" 5 #import "chrome/browser/cocoa/tabpose_window.h"
6 6
7 #import <QuartzCore/QuartzCore.h> 7 #import <QuartzCore/QuartzCore.h>
8 8
9 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "base/mac_util.h" 10 #include "base/mac_util.h"
11 #include "base/scoped_callback_factory.h" 11 #include "base/scoped_callback_factory.h"
12 #include "base/sys_string_conversions.h" 12 #include "base/sys_string_conversions.h"
13 #include "chrome/app/chrome_dll_resource.h"
13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/browser_process.h"
14 #import "chrome/browser/cocoa/bookmark_bar_constants.h" 15 #import "chrome/browser/cocoa/bookmark_bar_constants.h"
15 #import "chrome/browser/cocoa/browser_window_controller.h" 16 #import "chrome/browser/cocoa/browser_window_controller.h"
16 #import "chrome/browser/cocoa/tab_strip_controller.h" 17 #import "chrome/browser/cocoa/tab_strip_controller.h"
17 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" 18 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
18 #import "chrome/browser/debugger/devtools_window.h" 19 #import "chrome/browser/debugger/devtools_window.h"
19 #include "chrome/browser/prefs/pref_service.h" 20 #include "chrome/browser/prefs/pref_service.h"
20 #include "chrome/browser/renderer_host/backing_store_mac.h" 21 #include "chrome/browser/renderer_host/backing_store_mac.h"
21 #include "chrome/browser/renderer_host/render_view_host.h" 22 #include "chrome/browser/renderer_host/render_view_host.h"
22 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" 23 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 // Computes coordinates for |tiles_|. 456 // Computes coordinates for |tiles_|.
456 void Layout(NSRect containing_rect); 457 void Layout(NSRect containing_rect);
457 458
458 int selected_index() const { return selected_index_; } 459 int selected_index() const { return selected_index_; }
459 void set_selected_index(int index); 460 void set_selected_index(int index);
460 461
461 const Tile& selected_tile() const { return *tiles_[selected_index()]; } 462 const Tile& selected_tile() const { return *tiles_[selected_index()]; }
462 Tile& tile_at(int index) { return *tiles_[index]; } 463 Tile& tile_at(int index) { return *tiles_[index]; }
463 const Tile& tile_at(int index) const { return *tiles_[index]; } 464 const Tile& tile_at(int index) const { return *tiles_[index]; }
464 465
466 // These return which index needs to be selected when the user presses
467 // up, down, left, or right respectively.
468 int up_index() const;
469 int down_index() const;
470 int left_index() const;
471 int right_index() const;
472
473 // These return which index needs to be selected on tab / shift-tab.
474 int next_index() const;
475 int previous_index() const;
476
465 // Inserts a new Tile object containing |contents| at |index|. Does no 477 // Inserts a new Tile object containing |contents| at |index|. Does no
466 // relayout. 478 // relayout.
467 void InsertTileAt(int index, TabContents* contents); 479 void InsertTileAt(int index, TabContents* contents);
468 480
469 // Removes the Tile object at |index|. Does no relayout. 481 // Removes the Tile object at |index|. Does no relayout.
470 void RemoveTileAt(int index); 482 void RemoveTileAt(int index);
471 483
472 // Moves the Tile object at |from_index| to |to_index|. Since this doesn't 484 // Moves the Tile object at |from_index| to |to_index|. Since this doesn't
473 // change the number of tiles, relayout can be done just by swapping the 485 // change the number of tiles, relayout can be done just by swapping the
474 // tile rectangles in the index interval [from_index, to_index], so this does 486 // tile rectangles in the index interval [from_index, to_index], so this does
475 // layout. 487 // layout.
476 void MoveTileFromTo(int from_index, int to_index); 488 void MoveTileFromTo(int from_index, int to_index);
477 489
478 private: 490 private:
491 int count_x() const {
492 return ceilf(tiles_.size() / static_cast<float>(count_y_));
493 }
494 int count_y() const {
495 return count_y_;
496 }
497 int last_row_count_x() const {
498 return tiles_.size() - count_x() * (count_y() - 1);
499 }
500 int tiles_in_row(int row) const {
501 return row != count_y() - 1 ? count_x() : last_row_count_x();
502 }
503 void index_to_tile_xy(int index, int* tile_x, int* tile_y) const {
504 *tile_x = index % count_x();
505 *tile_y = index / count_x();
506 }
507 int tile_xy_to_index(int tile_x, int tile_y) const {
508 return tile_y * count_x() + tile_x;
509 }
510
479 ScopedVector<Tile> tiles_; 511 ScopedVector<Tile> tiles_;
480 int selected_index_; 512 int selected_index_;
513 int count_y_;
481 514
482 DISALLOW_COPY_AND_ASSIGN(TileSet); 515 DISALLOW_COPY_AND_ASSIGN(TileSet);
483 }; 516 };
484 517
485 void TileSet::Build(TabStripModel* source_model) { 518 void TileSet::Build(TabStripModel* source_model) {
486 selected_index_ = source_model->selected_index(); 519 selected_index_ = source_model->selected_index();
487 tiles_.resize(source_model->count()); 520 tiles_.resize(source_model->count());
488 for (size_t i = 0; i < tiles_.size(); ++i) { 521 for (size_t i = 0; i < tiles_.size(); ++i) {
489 tiles_[i] = new Tile; 522 tiles_[i] = new Tile;
490 tiles_[i]->contents_ = source_model->GetTabContentsAt(i); 523 tiles_[i]->contents_ = source_model->GetTabContentsAt(i);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 // |count_x * count_y >= tile_count|, and such that wasted space is minimized. 568 // |count_x * count_y >= tile_count|, and such that wasted space is minimized.
536 // See the comments in 569 // See the comments in
537 // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding()| for a more 570 // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding()| for a more
538 // detailed discussion. 571 // detailed discussion.
539 // TODO(thakis): It might be good enough to choose |count_x| and |count_y| 572 // TODO(thakis): It might be good enough to choose |count_x| and |count_y|
540 // such that count_x / count_y is roughly equal to |aspect|? 573 // such that count_x / count_y is roughly equal to |aspect|?
541 double fny = FitNRectsWithAspectIntoBoundingSizeWithConstantPadding( 574 double fny = FitNRectsWithAspectIntoBoundingSizeWithConstantPadding(
542 tile_count, aspect, 575 tile_count, aspect,
543 container_width, container_height - kFooterExtraHeight, 576 container_width, container_height - kFooterExtraHeight,
544 kSmallPaddingX, kSmallPaddingY + kFooterExtraHeight); 577 kSmallPaddingX, kSmallPaddingY + kFooterExtraHeight);
545 int count_y(roundf(fny)); 578 count_y_ = roundf(fny);
546 int count_x(ceilf(tile_count / float(count_y)));
547 int last_row_count_x = tile_count - count_x * (count_y - 1);
548 579
549 // Now that |count_x| and |count_y| are known, it's straightforward to compute 580 // Now that |count_x()| and |count_y_| are known, it's straightforward to
550 // thumbnail width/height. See comment in 581 // compute thumbnail width/height. See comment in
551 // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding| for the derivation 582 // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding| for the derivation
552 // of these two formulas. 583 // of these two formulas.
553 int small_width = 584 int small_width =
554 floor((container_width + kSmallPaddingX) / float(count_x) - 585 floor((container_width + kSmallPaddingX) / static_cast<float>(count_x()) -
555 kSmallPaddingX); 586 kSmallPaddingX);
556 int small_height = 587 int small_height =
557 floor((container_height + kSmallPaddingY) / float(count_y) - 588 floor((container_height + kSmallPaddingY) / static_cast<float>(count_y_) -
558 (kSmallPaddingY + kFooterExtraHeight)); 589 (kSmallPaddingY + kFooterExtraHeight));
559 590
560 // |small_width / small_height| has only roughly an aspect ratio of |aspect|. 591 // |small_width / small_height| has only roughly an aspect ratio of |aspect|.
561 // Shrink the thumbnail rect to make the aspect ratio fit exactly, and add 592 // Shrink the thumbnail rect to make the aspect ratio fit exactly, and add
562 // the extra space won by shrinking to the outer padding. 593 // the extra space won by shrinking to the outer padding.
563 int smallExtraPaddingLeft = 0; 594 int smallExtraPaddingLeft = 0;
564 int smallExtraPaddingTop = 0; 595 int smallExtraPaddingTop = 0;
565 if (aspect > small_width/float(small_height)) { 596 if (aspect > small_width/static_cast<float>(small_height)) {
566 small_height = small_width / aspect; 597 small_height = small_width / aspect;
567 CGFloat all_tiles_height = 598 CGFloat all_tiles_height =
568 (small_height + kSmallPaddingY + kFooterExtraHeight) * count_y - 599 (small_height + kSmallPaddingY + kFooterExtraHeight) * count_y() -
569 (kSmallPaddingY + kFooterExtraHeight); 600 (kSmallPaddingY + kFooterExtraHeight);
570 smallExtraPaddingTop = (container_height - all_tiles_height)/2; 601 smallExtraPaddingTop = (container_height - all_tiles_height)/2;
571 } else { 602 } else {
572 small_width = small_height * aspect; 603 small_width = small_height * aspect;
573 CGFloat all_tiles_width = 604 CGFloat all_tiles_width =
574 (small_width + kSmallPaddingX) * count_x - kSmallPaddingX; 605 (small_width + kSmallPaddingX) * count_x() - kSmallPaddingX;
575 smallExtraPaddingLeft = (container_width - all_tiles_width)/2; 606 smallExtraPaddingLeft = (container_width - all_tiles_width)/2;
576 } 607 }
577 608
578 // Compute inter-tile padding in the zoomed-out view. 609 // Compute inter-tile padding in the zoomed-out view.
579 CGFloat scale_small_to_big = NSWidth(containing_rect) / float(small_width); 610 CGFloat scale_small_to_big =
611 NSWidth(containing_rect) / static_cast<float>(small_width);
580 CGFloat big_padding_x = kSmallPaddingX * scale_small_to_big; 612 CGFloat big_padding_x = kSmallPaddingX * scale_small_to_big;
581 CGFloat big_padding_y = 613 CGFloat big_padding_y =
582 (kSmallPaddingY + kFooterExtraHeight) * scale_small_to_big; 614 (kSmallPaddingY + kFooterExtraHeight) * scale_small_to_big;
583 615
584 // Now all dimensions are known. Lay out all tiles on a regular grid: 616 // Now all dimensions are known. Lay out all tiles on a regular grid:
585 // X X X X 617 // X X X X
586 // X X X X 618 // X X X X
587 // X X 619 // X X
588 for (int row = 0, i = 0; i < tile_count; ++row) { 620 for (int row = 0, i = 0; i < tile_count; ++row) {
589 for (int col = 0; col < count_x && i < tile_count; ++col, ++i) { 621 for (int col = 0; col < count_x() && i < tile_count; ++col, ++i) {
590 // Compute the smalled, zoomed-out thumbnail rect. 622 // Compute the smalled, zoomed-out thumbnail rect.
591 tiles_[i]->thumb_rect_.size = NSMakeSize(small_width, small_height); 623 tiles_[i]->thumb_rect_.size = NSMakeSize(small_width, small_height);
592 624
593 int small_x = col * (small_width + kSmallPaddingX) + 625 int small_x = col * (small_width + kSmallPaddingX) +
594 kSmallPaddingLeft + smallExtraPaddingLeft; 626 kSmallPaddingLeft + smallExtraPaddingLeft;
595 int small_y = row * (small_height + kSmallPaddingY + kFooterExtraHeight) + 627 int small_y = row * (small_height + kSmallPaddingY + kFooterExtraHeight) +
596 kSmallPaddingTop + smallExtraPaddingTop; 628 kSmallPaddingTop + smallExtraPaddingTop;
597 629
598 tiles_[i]->thumb_rect_.origin = NSMakePoint( 630 tiles_[i]->thumb_rect_.origin = NSMakePoint(
599 small_x, NSHeight(containing_rect) - small_y - small_height); 631 small_x, NSHeight(containing_rect) - small_y - small_height);
(...skipping 22 matching lines...) Expand all
622 int big_x = col * (NSWidth(containing_rect) + big_padding_x); 654 int big_x = col * (NSWidth(containing_rect) + big_padding_x);
623 int big_y = row * (NSHeight(containing_rect) + big_padding_y); 655 int big_y = row * (NSHeight(containing_rect) + big_padding_y);
624 tiles_[i]->start_thumb_rect_.origin = NSMakePoint(big_x, -big_y); 656 tiles_[i]->start_thumb_rect_.origin = NSMakePoint(big_x, -big_y);
625 } 657 }
626 } 658 }
627 659
628 // Go through last row and center it: 660 // Go through last row and center it:
629 // X X X X 661 // X X X X
630 // X X X X 662 // X X X X
631 // X X 663 // X X
632 int last_row_empty_tiles_x = count_x - last_row_count_x; 664 int last_row_empty_tiles_x = count_x() - last_row_count_x();
633 CGFloat small_last_row_shift_x = 665 CGFloat small_last_row_shift_x =
634 last_row_empty_tiles_x * (small_width + kSmallPaddingX) / 2; 666 last_row_empty_tiles_x * (small_width + kSmallPaddingX) / 2;
635 CGFloat big_last_row_shift_x = 667 CGFloat big_last_row_shift_x =
636 last_row_empty_tiles_x * (NSWidth(containing_rect) + big_padding_x) / 2; 668 last_row_empty_tiles_x * (NSWidth(containing_rect) + big_padding_x) / 2;
637 for (int i = tile_count - last_row_count_x; i < tile_count; ++i) { 669 for (int i = tile_count - last_row_count_x(); i < tile_count; ++i) {
638 tiles_[i]->thumb_rect_.origin.x += small_last_row_shift_x; 670 tiles_[i]->thumb_rect_.origin.x += small_last_row_shift_x;
639 tiles_[i]->start_thumb_rect_.origin.x += big_last_row_shift_x; 671 tiles_[i]->start_thumb_rect_.origin.x += big_last_row_shift_x;
640 tiles_[i]->favicon_rect_.origin.x += small_last_row_shift_x; 672 tiles_[i]->favicon_rect_.origin.x += small_last_row_shift_x;
641 tiles_[i]->title_rect_.origin.x += small_last_row_shift_x; 673 tiles_[i]->title_rect_.origin.x += small_last_row_shift_x;
642 } 674 }
643 } 675 }
644 676
645 void TileSet::set_selected_index(int index) { 677 void TileSet::set_selected_index(int index) {
646 CHECK_GE(index, 0); 678 CHECK_GE(index, 0);
647 CHECK_LT(index, static_cast<int>(tiles_.size())); 679 CHECK_LT(index, static_cast<int>(tiles_.size()));
648 selected_index_ = index; 680 selected_index_ = index;
649 } 681 }
650 682
683 // Given a |value| in [0, from_scale), map it into [0, to_scale) such that:
684 // * [0, from_scale) ends up in the middle of [0, to_scale) if the latter is
685 // a bigger range
686 // * The middle of [0, from_scale) is mapped to [0, to_scale), and the parts
687 // of the former that don't fit are mapped to 0 and to_scale - respectively
688 // if the former is a bigger range.
689 static int rescale(int value, int from_scale, int to_scale) {
690 int left = (to_scale - from_scale) / 2;
691 int result = value + left;
692 if (result < 0)
693 return 0;
694 if (result >= to_scale)
695 return to_scale - 1;
696 return result;
697 }
698
699 int TileSet::up_index() const {
700 int tile_x, tile_y;
701 index_to_tile_xy(selected_index(), &tile_x, &tile_y);
702 tile_y -= 1;
703 if (tile_y == count_y() - 2) {
704 // Transition from last row to second-to-last row.
705 tile_x = rescale(tile_x, last_row_count_x(), count_x());
706 } else if (tile_y < 0) {
707 // Transition from first row to last row.
708 tile_x = rescale(tile_x, count_x(), last_row_count_x());
709 tile_y = count_y() - 1;
710 }
711 return tile_xy_to_index(tile_x, tile_y);
712 }
713
714 int TileSet::down_index() const {
715 int tile_x, tile_y;
716 index_to_tile_xy(selected_index(), &tile_x, &tile_y);
717 tile_y += 1;
718 if (tile_y == count_y() - 1) {
719 // Transition from second-to-last row to last row.
720 tile_x = rescale(tile_x, count_x(), last_row_count_x());
721 } else if (tile_y >= count_y()) {
722 // Transition from last row to first row.
723 tile_x = rescale(tile_x, last_row_count_x(), count_x());
724 tile_y = 0;
725 }
726 return tile_xy_to_index(tile_x, tile_y);
727 }
728
729 int TileSet::left_index() const {
730 int tile_x, tile_y;
731 index_to_tile_xy(selected_index(), &tile_x, &tile_y);
732 tile_x -= 1;
733 if (tile_x < 0)
734 tile_x = tiles_in_row(tile_y) - 1;
735 return tile_xy_to_index(tile_x, tile_y);
736 }
737
738 int TileSet::right_index() const {
739 int tile_x, tile_y;
740 index_to_tile_xy(selected_index(), &tile_x, &tile_y);
741 tile_x += 1;
742 if (tile_x >= tiles_in_row(tile_y))
743 tile_x = 0;
744 return tile_xy_to_index(tile_x, tile_y);
745 }
746
747 int TileSet::next_index() const {
748 int new_index = selected_index() + 1;
749 if (new_index >= static_cast<int>(tiles_.size()))
viettrungluu 2010/09/16 20:07:21 I think this would be a fine place to use ?:.
Nico 2010/09/16 20:08:54 but then i need to write "+1" twice!
750 new_index = 0;
751 return new_index;
752 }
753
754 int TileSet::previous_index() const {
755 int new_index = selected_index() - 1;
756 if (new_index < 0)
viettrungluu 2010/09/16 20:07:21 Ditto.
757 new_index = tiles_.size() - 1;
758 return new_index;
759 }
760
651 void TileSet::InsertTileAt(int index, TabContents* contents) { 761 void TileSet::InsertTileAt(int index, TabContents* contents) {
652 tiles_.insert(tiles_.begin() + index, new Tile); 762 tiles_.insert(tiles_.begin() + index, new Tile);
653 tiles_[index]->contents_ = contents; 763 tiles_[index]->contents_ = contents;
654 } 764 }
655 765
656 void TileSet::RemoveTileAt(int index) { 766 void TileSet::RemoveTileAt(int index) {
657 tiles_.erase(tiles_.begin() + index); 767 tiles_.erase(tiles_.begin() + index);
658 } 768 }
659 769
660 // Moves the Tile object at |from_index| to |to_index|. Also updates rectangles 770 // Moves the Tile object at |from_index| to |to_index|. Also updates rectangles
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // there's a one frame flash of grey at the beginning of the animation 1038 // there's a one frame flash of grey at the beginning of the animation
929 // (|bgLayer_| showing through with none of its children visible yet). 1039 // (|bgLayer_| showing through with none of its children visible yet).
930 [[self contentView] setLayer:rootLayer_]; 1040 [[self contentView] setLayer:rootLayer_];
931 [[self contentView] setWantsLayer:YES]; 1041 [[self contentView] setWantsLayer:YES];
932 } 1042 }
933 1043
934 - (BOOL)canBecomeKeyWindow { 1044 - (BOOL)canBecomeKeyWindow {
935 return YES; 1045 return YES;
936 } 1046 }
937 1047
1048 // Handle key events that should be executed repeatedly while the key is down.
938 - (void)keyDown:(NSEvent*)event { 1049 - (void)keyDown:(NSEvent*)event {
939 // Overridden to prevent beeps. 1050 if (state_ == tabpose::kFadingOut)
1051 return;
1052 NSString* characters = [event characters];
1053 if ([characters length] < 1)
1054 return;
1055
1056 unichar character = [characters characterAtIndex:0];
1057 int newIndex = -1;
1058 switch (character) {
1059 case NSUpArrowFunctionKey:
1060 newIndex = tileSet_->up_index();
1061 break;
1062 case NSDownArrowFunctionKey:
1063 newIndex = tileSet_->down_index();
1064 break;
1065 case NSLeftArrowFunctionKey:
1066 newIndex = tileSet_->left_index();
1067 break;
1068 case NSRightArrowFunctionKey:
1069 newIndex = tileSet_->right_index();
1070 break;
1071 case NSTabCharacter:
1072 newIndex = tileSet_->next_index();
1073 break;
1074 case NSBackTabCharacter:
1075 newIndex = tileSet_->previous_index();
1076 break;
1077 }
1078 if (newIndex != -1)
1079 [self selectTileAtIndexWithoutAnimation:newIndex];
940 } 1080 }
941 1081
1082 // Handle keyboard events that should be executed once when the key is released.
942 - (void)keyUp:(NSEvent*)event { 1083 - (void)keyUp:(NSEvent*)event {
943 if (state_ == tabpose::kFadingOut) 1084 if (state_ == tabpose::kFadingOut)
944 return; 1085 return;
945
946 NSString* characters = [event characters]; 1086 NSString* characters = [event characters];
947 if ([characters length] < 1) 1087 if ([characters length] < 1)
948 return; 1088 return;
949 1089
950 unichar character = [characters characterAtIndex:0]; 1090 unichar character = [characters characterAtIndex:0];
951 switch (character) { 1091 switch (character) {
952 case NSEnterCharacter: 1092 case NSEnterCharacter:
953 case NSNewlineCharacter: 1093 case NSNewlineCharacter:
954 case NSCarriageReturnCharacter: 1094 case NSCarriageReturnCharacter:
955 case ' ': 1095 case ' ':
956 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; 1096 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0];
957 break; 1097 break;
958 case '\e': // Escape 1098 case '\e': // Escape
959 tileSet_->set_selected_index(tabStripModel_->selected_index()); 1099 tileSet_->set_selected_index(tabStripModel_->selected_index());
960 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0]; 1100 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0];
961 break; 1101 break;
962 // TODO(thakis): Support moving the selection via arrow keys.
963 } 1102 }
964 } 1103 }
965 1104
1105 // Handle keyboard events that contain cmd or ctrl.
1106 - (BOOL)performKeyEquivalent:(NSEvent*)event {
1107 if (state_ == tabpose::kFadingOut)
1108 return NO;
1109 NSString* characters = [event characters];
1110 if ([characters length] < 1)
1111 return NO;
1112 unichar character = [characters characterAtIndex:0];
1113 if ([event modifierFlags] & NSCommandKeyMask) {
1114 if (character >= '1' && character <= '9') {
1115 int index =
1116 character == '9' ? tabStripModel_->count() - 1 : character - '1';
1117 if (index < tabStripModel_->count()) {
1118 tileSet_->set_selected_index(index);
1119 [self fadeAway:([event modifierFlags] & NSShiftKeyMask) != 0];
1120 return YES;
1121 }
1122 }
1123 }
1124 return NO;
1125 }
1126
966 - (void)mouseMoved:(NSEvent*)event { 1127 - (void)mouseMoved:(NSEvent*)event {
967 int newIndex = -1; 1128 int newIndex = -1;
968 CGPoint p = NSPointToCGPoint([event locationInWindow]); 1129 CGPoint p = NSPointToCGPoint([event locationInWindow]);
969 for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { 1130 for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) {
970 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; 1131 CALayer* layer = [allThumbnailLayers_ objectAtIndex:i];
971 CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_]; 1132 CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_];
972 if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp]) 1133 if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp])
973 newIndex = i; 1134 newIndex = i;
974 } 1135 }
975 if (newIndex >= 0) 1136 if (newIndex >= 0)
(...skipping 14 matching lines...) Expand all
990 [[self parentWindow] removeChildWindow:self]; 1151 [[self parentWindow] removeChildWindow:self];
991 1152
992 // We're dealloc'd in an autorelease pool – by then the observer registry 1153 // We're dealloc'd in an autorelease pool – by then the observer registry
993 // might be dead, so explicitly reset the observer now. 1154 // might be dead, so explicitly reset the observer now.
994 tabStripModelObserverBridge_.reset(); 1155 tabStripModelObserverBridge_.reset();
995 1156
996 [super close]; 1157 [super close];
997 } 1158 }
998 1159
999 - (void)commandDispatch:(id)sender { 1160 - (void)commandDispatch:(id)sender {
1000 // Without this, -validateUserInterfaceItem: is not called. 1161 if ([sender tag] == IDC_TABPOSE)
1162 [self fadeAway:NO];
1001 } 1163 }
1002 1164
1003 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { 1165 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
1004 // Disable all browser-related menu items. 1166 // Disable all browser-related menu items except the tab overview toggle.
1005 return NO; 1167 SEL action = [item action];
1168 NSInteger tag = [item tag];
1169 return action == @selector(commandDispatch:) && tag == IDC_TABPOSE;
1006 } 1170 }
1007 1171
1008 - (void)fadeAway:(BOOL)slomo { 1172 - (void)fadeAway:(BOOL)slomo {
1009 if (state_ == tabpose::kFadingOut) 1173 if (state_ == tabpose::kFadingOut)
1010 return; 1174 return;
1011 1175
1012 state_ = tabpose::kFadingOut; 1176 state_ = tabpose::kFadingOut;
1013 [self setAcceptsMouseMovedEvents:NO]; 1177 [self setAcceptsMouseMovedEvents:NO];
1014 1178
1015 // Select chosen tab. 1179 // Select chosen tab.
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 tile.set_tab_contents(contents); 1417 tile.set_tab_contents(contents);
1254 ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index]; 1418 ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index];
1255 [thumbLayer setTabContents:contents]; 1419 [thumbLayer setTabContents:contents];
1256 } 1420 }
1257 1421
1258 - (void)tabStripModelDeleted { 1422 - (void)tabStripModelDeleted {
1259 [self close]; 1423 [self close];
1260 } 1424 }
1261 1425
1262 @end 1426 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698