diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-04 16:44:28 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-04 16:44:28 +0000 |
commit | d9310e73313623e83708e0ba4e242343ddb71beb (patch) | |
tree | 4334cca622bedaa7d6dbb9fd5845ba073e6ea443 | |
parent | 91043a823d2ffda5d5a1c8f026173777aac35f83 (diff) | |
download | chromium_src-d9310e73313623e83708e0ba4e242343ddb71beb.zip chromium_src-d9310e73313623e83708e0ba4e242343ddb71beb.tar.gz chromium_src-d9310e73313623e83708e0ba4e242343ddb71beb.tar.bz2 |
Makes launcher handle overflow.
BUG=101505
TEST=none
R=ben@chromium.org
Review URL: http://codereview.chromium.org/8334036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108667 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/aura/window.cc | 5 | ||||
-rw-r--r-- | ui/aura/window.h | 5 | ||||
-rw-r--r-- | ui/aura_shell/launcher/launcher_view.cc | 151 | ||||
-rw-r--r-- | ui/aura_shell/launcher/launcher_view.h | 19 | ||||
-rwxr-xr-x | ui/resources/aura/launcher_overflow.png | bin | 0 -> 1695 bytes | |||
-rw-r--r-- | ui/resources/ui_resources.grd | 1 | ||||
-rw-r--r-- | views/widget/native_widget_aura.cc | 2 |
7 files changed, 171 insertions, 12 deletions
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 45dcf0ea..17f1b50 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -100,12 +100,11 @@ bool Window::IsVisible() const { } gfx::Rect Window::GetScreenBounds() const { - const gfx::Rect local_bounds = bounds(); - gfx::Point origin = local_bounds.origin(); + gfx::Point origin = bounds().origin(); Window::ConvertPointToWindow(parent_, aura::Desktop::GetInstance(), &origin); - return gfx::Rect(origin, local_bounds.size()); + return gfx::Rect(origin, bounds().size()); } void Window::Activate() { diff --git a/ui/aura/window.h b/ui/aura/window.h index bab696d..df3e1aa 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h @@ -72,6 +72,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate { const std::string& name() const { return name_; } void set_name(const std::string& name) { name_ = name; } + const string16 title() const { return title_; } + void set_title(const string16& title) { title_ = title; } + ui::Layer* layer() { return layer_.get(); } const ui::Layer* layer() const { return layer_.get(); } @@ -327,6 +330,8 @@ class AURA_EXPORT Window : public ui::LayerDelegate { int id_; std::string name_; + string16 title_; + scoped_ptr<EventFilter> event_filter_; scoped_ptr<LayoutManager> layout_manager_; diff --git a/ui/aura_shell/launcher/launcher_view.cc b/ui/aura_shell/launcher/launcher_view.cc index fe4fb79..6d22e5a 100644 --- a/ui/aura_shell/launcher/launcher_view.cc +++ b/ui/aura_shell/launcher/launcher_view.cc @@ -13,13 +13,17 @@ #include "ui/aura_shell/launcher/view_model_utils.h" #include "ui/aura_shell/shell.h" #include "ui/aura_shell/shell_delegate.h" +#include "ui/aura/window.h" #include "ui/base/animation/animation.h" #include "ui/base/animation/throb_animation.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/compositor/layer.h" #include "ui/gfx/image/image.h" #include "views/animation/bounds_animator.h" #include "views/controls/button/image_button.h" +#include "views/controls/menu/menu_model_adapter.h" +#include "views/controls/menu/menu_runner.h" #include "views/widget/widget.h" using ui::Animation; @@ -47,6 +51,37 @@ static const float kDimmedButtonOpacity = .8f; namespace { +// ui::SimpleMenuModel::Delegate implementation that remembers the id of the +// menu that was activated. +class MenuDelegateImpl : public ui::SimpleMenuModel::Delegate { + public: + MenuDelegateImpl() : activated_command_id_(-1) {} + + int activated_command_id() const { return activated_command_id_; } + + // ui::SimpleMenuModel::Delegate overrides: + virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { + return false; + } + virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { + return true; + } + virtual bool GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) OVERRIDE { + return false; + } + virtual void ExecuteCommand(int command_id) OVERRIDE { + activated_command_id_ = command_id; + } + + private: + // ID of the command passed to ExecuteCommand. + int activated_command_id_; + + DISALLOW_COPY_AND_ASSIGN(MenuDelegateImpl); +}; + // ImageButton subclass that animates transition changes using the opacity of // the layer. class FadeButton : public views::ImageButton { @@ -195,6 +230,7 @@ LauncherView::LauncherView(LauncherModel* model) view_model_(new ViewModel), new_browser_button_(NULL), show_apps_button_(NULL), + overflow_button_(NULL), dragging_(NULL), drag_view_(NULL), drag_offset_(0), @@ -232,7 +268,15 @@ void LauncherView::Init() { ConfigureChildView(show_apps_button_); AddChildView(show_apps_button_); - LayoutToIdealBounds(); + overflow_button_ = new FadeButton(this); + // TODO: need image for this. + overflow_button_->SetImage( + views::CustomButton::BS_NORMAL, + rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToSkBitmap()); + ConfigureChildView(overflow_button_); + AddChildView(overflow_button_); + + // We'll layout when our bounds change. } void LauncherView::LayoutToIdealBounds() { @@ -244,6 +288,10 @@ void LauncherView::LayoutToIdealBounds() { } void LauncherView::CalculateIdealBounds(IdealBounds* bounds) { + int available_width = width(); + if (!available_width) + return; + // new_browser_button first. int x = kLeadingInset; gfx::Size pref = new_browser_button_->GetPreferredSize(); @@ -260,12 +308,45 @@ void LauncherView::CalculateIdealBounds(IdealBounds* bounds) { x += pref.width() + kHorizontalPadding; } - // And the show_apps_button. - pref = show_apps_button_->GetPreferredSize(); + // Show apps button and overflow button. + bounds->show_apps_bounds.set_size(show_apps_button_->GetPreferredSize()); + bounds->overflow_bounds.set_size(overflow_button_->GetPreferredSize()); + int last_visible_index = DetermineLastVisibleIndex( + available_width - kLeadingInset - bounds->show_apps_bounds.width() - + kHorizontalPadding - bounds->overflow_bounds.width() - + kHorizontalPadding); + bool show_overflow = (last_visible_index + 1 != view_model_->view_size()); + if (overflow_button_->IsVisible() != show_overflow) { + // Only change visibility of the views if the visibility of the overflow + // button changes. Otherwise we'll effect the insertion animation, which + // changes the visibility. + for (int i = 0; i <= last_visible_index; ++i) + view_model_->view_at(i)->SetVisible(true); + for (int i = last_visible_index + 1; i < view_model_->view_size(); ++i) + view_model_->view_at(i)->SetVisible(false); + } + + overflow_button_->SetVisible(show_overflow); + if (show_overflow) { + DCHECK_NE(0, view_model_->view_size()); + x = view_model_->ideal_bounds(last_visible_index).right() + + kHorizontalPadding; + bounds->overflow_bounds.set_x(x); + bounds->overflow_bounds.set_y( + (kPreferredHeight - bounds->overflow_bounds.height()) / 2); + x = bounds->overflow_bounds.right() + kHorizontalPadding; + } // TODO(sky): -8 is a hack, remove when we get better images. - bounds->show_apps_bounds = gfx::Rect( - x - 8, (kPreferredHeight - pref.width()) / 2, pref.width(), - pref.height()); + bounds->show_apps_bounds.set_x(x - 8); + bounds->show_apps_bounds.set_y( + (kPreferredHeight - bounds->show_apps_bounds.height()) / 2); +} + +int LauncherView::DetermineLastVisibleIndex(int max_x) { + int index = view_model_->view_size() - 1; + while (index >= 0 && view_model_->ideal_bounds(index).right() > max_x) + index--; + return index; } void LauncherView::AnimateToIdealBounds() { @@ -279,6 +360,7 @@ void LauncherView::AnimateToIdealBounds() { } bounds_animator_->AnimateViewTo(show_apps_button_, ideal_bounds.show_apps_bounds); + overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); } views::View* LauncherView::CreateViewForItem(const LauncherItem& item) { @@ -351,6 +433,51 @@ void LauncherView::ConfigureChildView(views::View* view) { view->layer()->SetFillsBoundsOpaquely(false); } +void LauncherView::GetOverflowWindows(std::vector<aura::Window*>* names) { + int index = 0; + while (index < view_model_->view_size() && + view_model_->view_at(index)->IsVisible()) { + index++; + } + while (index < view_model_->view_size()) { + names->push_back(model_->items()[index].window); + index++; + } +} + +void LauncherView::ShowOverflowMenu() { + std::vector<aura::Window*> windows; + GetOverflowWindows(&windows); + if (windows.empty()) + return; + + MenuDelegateImpl menu_delegate; + ui::SimpleMenuModel menu_model(&menu_delegate); + for (size_t i = 0; i < windows.size(); ++i) + menu_model.AddItem(static_cast<int>(i), windows[i]->title()); + views::MenuModelAdapter menu_adapter(&menu_model); + overflow_menu_runner_.reset(new views::MenuRunner(menu_adapter.CreateMenu())); + gfx::Rect bounds(overflow_button_->size()); + gfx::Point origin; + ConvertPointToScreen(overflow_button_, &origin); + if (overflow_menu_runner_->RunMenuAt(GetWidget(), NULL, + gfx::Rect(origin, size()), views::MenuItemView::TOPLEFT, 0) == + views::MenuRunner::MENU_DELETED || + menu_delegate.activated_command_id() == -1) + return; + + aura::Window* activated_window = + windows[menu_delegate.activated_command_id()]; + LauncherItems::const_iterator window_iter = + model_->ItemByWindow(activated_window); + if (window_iter == model_->items().end()) + return; // Window was deleted while menu was up. + ShellDelegate* delegate = Shell::GetInstance()->delegate(); + if (!delegate) + return; + delegate->LauncherItemClicked(*window_iter); +} + void LauncherView::CancelDrag(views::View* deleted_view) { if (!drag_view_) return; @@ -376,6 +503,10 @@ gfx::Size LauncherView::GetPreferredSize() { kPreferredHeight); } +void LauncherView::OnBoundsChanged(const gfx::Rect& previous_bounds) { + LayoutToIdealBounds(); +} + void LauncherView::LauncherItemAdded(int model_index) { CancelDrag(NULL); @@ -389,8 +520,10 @@ void LauncherView::LauncherItemAdded(int model_index) { // hidden, so it visually appears as though we are providing space for // it. When done we'll fade the view in. AnimateToIdealBounds(); - bounds_animator_->SetAnimationDelegate( - view, new StartFadeAnimationDelegate(this, view), true); + if (!overflow_button_->IsVisible()) { + bounds_animator_->SetAnimationDelegate( + view, new StartFadeAnimationDelegate(this, view), true); + } } void LauncherView::LauncherItemRemoved(int model_index) { @@ -466,6 +599,8 @@ void LauncherView::ButtonPressed(views::Button* sender, delegate->CreateNewWindow(); } else if (sender == show_apps_button_) { delegate->ShowApps(); + } else if (sender == overflow_button_) { + ShowOverflowMenu(); } else { int view_index = view_model_->GetIndexOfView(sender); // May be -1 while in the process of animating closed. diff --git a/ui/aura_shell/launcher/launcher_view.h b/ui/aura_shell/launcher/launcher_view.h index b5d0320..a2f63b3 100644 --- a/ui/aura_shell/launcher/launcher_view.h +++ b/ui/aura_shell/launcher/launcher_view.h @@ -6,6 +6,8 @@ #define UI_AURA_SHELL_LAUNCHER_VIEW_H_ #pragma once +#include <vector> + #include "ui/aura_shell/launcher/launcher_button_host.h" #include "ui/aura_shell/launcher/launcher_model_observer.h" #include "views/controls/button/button.h" @@ -14,6 +16,7 @@ namespace views { class BoundsAnimator; class ImageButton; +class MenuRunner; } namespace aura_shell { @@ -41,6 +44,7 @@ class LauncherView : public views::WidgetDelegateView, struct IdealBounds { gfx::Rect new_browser_bounds; gfx::Rect show_apps_bounds; + gfx::Rect overflow_bounds; }; // Sets the bounds of each view to its ideal bounds. @@ -51,6 +55,10 @@ class LauncherView : public views::WidgetDelegateView, // |new_browser_button_| and |show_apps_button_| is set in |bounds|. void CalculateIdealBounds(IdealBounds* bounds); + // Returns the index of the last view whose max x-coordinate is less than + // |max_x|. Returns -1 if nothing fits, or there are no views. + int DetermineLastVisibleIndex(int max_x); + // Animates the bounds of each view to its ideal bounds. void AnimateToIdealBounds(); @@ -73,8 +81,15 @@ class LauncherView : public views::WidgetDelegateView, // Common setup done for all children. void ConfigureChildView(views::View* view); + // Returns the windows whose icon is not show because it doesn't fit. + void GetOverflowWindows(std::vector<aura::Window*>* names); + + // Shows the overflow menu. + void ShowOverflowMenu(); + // Overridden from views::View: virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; // Overridden from LauncherModelObserver: virtual void LauncherItemAdded(int model_index) OVERRIDE; @@ -107,6 +122,8 @@ class LauncherView : public views::WidgetDelegateView, views::ImageButton* show_apps_button_; + views::ImageButton* overflow_button_; + // Are we dragging? This is only set if the mouse is dragged far enough to // trigger a drag. bool dragging_; @@ -121,6 +138,8 @@ class LauncherView : public views::WidgetDelegateView, // Index |drag_view_| was initially at. int start_drag_index_; + scoped_ptr<views::MenuRunner> overflow_menu_runner_; + DISALLOW_COPY_AND_ASSIGN(LauncherView); }; diff --git a/ui/resources/aura/launcher_overflow.png b/ui/resources/aura/launcher_overflow.png Binary files differnew file mode 100755 index 0000000..5535278 --- /dev/null +++ b/ui/resources/aura/launcher_overflow.png diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd index c9670c2..4f294d2 100644 --- a/ui/resources/ui_resources.grd +++ b/ui/resources/ui_resources.grd @@ -131,6 +131,7 @@ <!-- Images only used by Aura. --> <if expr="pp_ifdef('use_aura')"> <include name="IDR_AURA_LAUNCHER_ICON_CHROME" file="aura/chromium-32.png" type="BINDATA" /> + <include name="IDR_AURA_LAUNCHER_OVERFLOW" file="aura/launcher_overflow.png" type="BINDATA" /> <include name="IDR_AURA_LAUNCHER_TABBED_BROWSER_1" file="aura/browser_instance_1.png" type="BINDATA" /> <include name="IDR_AURA_LAUNCHER_TABBED_BROWSER_2" file="aura/browser_instance_2.png" type="BINDATA" /> <include name="IDR_AURA_LAUNCHER_TABBED_BROWSER_3" file="aura/browser_instance_3.png" type="BINDATA" /> diff --git a/views/widget/native_widget_aura.cc b/views/widget/native_widget_aura.cc index 53d4216..cb4eeba 100644 --- a/views/widget/native_widget_aura.cc +++ b/views/widget/native_widget_aura.cc @@ -286,7 +286,7 @@ void NativeWidgetAura::GetWindowPlacement( } void NativeWidgetAura::SetWindowTitle(const string16& title) { - // Aura doesn't have native window frames. + window_->set_title(title); } void NativeWidgetAura::SetWindowIcons(const SkBitmap& window_icon, |