Home | History | Annotate | Download | only in wm
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "athena/wm/window_list_provider_impl.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "athena/wm/public/window_list_provider_observer.h"
     10 #include "ui/aura/window.h"
     11 
     12 namespace athena {
     13 
     14 WindowListProviderImpl::WindowListProviderImpl(aura::Window* container)
     15     : container_(container) {
     16   CHECK(container_);
     17   container_->AddObserver(this);
     18   RecreateWindowList();
     19   std::for_each(window_list_.begin(), window_list_.end(),
     20                 std::bind2nd(std::mem_fun(&aura::Window::AddObserver),
     21                              this));
     22 }
     23 
     24 WindowListProviderImpl::~WindowListProviderImpl() {
     25   // Remove all remaining window observers.
     26   for (aura::Window::Windows::const_iterator iter = window_list_.begin();
     27        iter != window_list_.end();
     28        ++iter) {
     29     CHECK(IsValidWindow(*iter));
     30     (*iter)->RemoveObserver(this);
     31   }
     32   container_->RemoveObserver(this);
     33 }
     34 
     35 void WindowListProviderImpl::RecreateWindowList() {
     36   window_list_.clear();
     37   const aura::Window::Windows& container_children = container_->children();
     38   for (aura::Window::Windows::const_iterator iter = container_children.begin();
     39        iter != container_children.end();
     40        ++iter) {
     41     if (IsValidWindow(*iter))
     42       window_list_.push_back(*iter);
     43   }
     44 }
     45 
     46 void WindowListProviderImpl::AddObserver(WindowListProviderObserver* observer) {
     47   observers_.AddObserver(observer);
     48 }
     49 
     50 void WindowListProviderImpl::RemoveObserver(
     51     WindowListProviderObserver* observer) {
     52   observers_.RemoveObserver(observer);
     53 }
     54 
     55 const aura::Window::Windows& WindowListProviderImpl::GetWindowList() const {
     56   return window_list_;
     57 }
     58 
     59 bool WindowListProviderImpl::IsWindowInList(aura::Window* window) const {
     60   return window->parent() == container_ && IsValidWindow(window);
     61 }
     62 
     63 bool WindowListProviderImpl::IsValidWindow(aura::Window* window) const {
     64   // TODO(oshima): crbug.com/413912
     65   return window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
     66       window->type() == ui::wm::WINDOW_TYPE_PANEL;
     67 }
     68 
     69 void WindowListProviderImpl::StackWindowFrontOf(
     70     aura::Window* window,
     71     aura::Window* reference_window) {
     72   DCHECK_NE(window, reference_window);
     73   DCHECK(IsWindowInList(window));
     74   DCHECK(IsWindowInList(reference_window));
     75   container_->StackChildAbove(window, reference_window);
     76 }
     77 
     78 void WindowListProviderImpl::StackWindowBehindTo(
     79     aura::Window* window,
     80     aura::Window* reference_window) {
     81   DCHECK_NE(window, reference_window);
     82   DCHECK(IsWindowInList(window));
     83   DCHECK(IsWindowInList(reference_window));
     84   container_->StackChildBelow(window, reference_window);
     85 }
     86 
     87 void WindowListProviderImpl::OnWindowAdded(aura::Window* window) {
     88   if (!IsValidWindow(window) || window->parent() != container_)
     89     return;
     90   RecreateWindowList();
     91   DCHECK(IsWindowInList(window));
     92   window->AddObserver(this);
     93 }
     94 
     95 void WindowListProviderImpl::OnWillRemoveWindow(aura::Window* window) {
     96   if (!IsValidWindow(window) || window->parent() != container_)
     97     return;
     98   DCHECK(IsWindowInList(window));
     99   aura::Window::Windows::iterator find = std::find(window_list_.begin(),
    100                                                    window_list_.end(),
    101                                                    window);
    102   CHECK(find != window_list_.end());
    103   int index = find - window_list_.begin();
    104   window_list_.erase(find);
    105   window->RemoveObserver(this);
    106   FOR_EACH_OBSERVER(
    107       WindowListProviderObserver, observers_, OnWindowRemoved(window, index));
    108 }
    109 
    110 void WindowListProviderImpl::OnWindowStackingChanged(aura::Window* window) {
    111   if (window == container_)
    112     return;
    113   DCHECK(IsWindowInList(window));
    114   RecreateWindowList();
    115   // Inform our listeners that the stacking has been changed.
    116   FOR_EACH_OBSERVER(WindowListProviderObserver,
    117                     observers_,
    118                     OnWindowStackingChanged());
    119 }
    120 
    121 }  // namespace athena
    122