This source file includes following definitions.
- Get
- Get
- AddObserver
- RemoveObserver
- AddTransientChild
- RemoveTransientChild
- IsStackingTransient
- stacking_pair_
- OnChildStackingChanged
- OnWindowVisibilityChanging
- OnWindowStackingChanged
- OnWindowDestroying
#include "ui/wm/core/transient_window_manager.h"
#include <algorithm>
#include <functional>
#include "base/auto_reset.h"
#include "base/stl_util.h"
#include "ui/aura/window.h"
#include "ui/aura/window_property.h"
#include "ui/wm/core/transient_window_observer.h"
#include "ui/wm/core/transient_window_stacking_client.h"
#include "ui/wm/core/window_util.h"
using aura::Window;
namespace wm {
DEFINE_OWNED_WINDOW_PROPERTY_KEY(TransientWindowManager, kPropertyKey, NULL);
TransientWindowManager::~TransientWindowManager() {
}
TransientWindowManager* TransientWindowManager::Get(Window* window) {
TransientWindowManager* manager = window->GetProperty(kPropertyKey);
if (!manager) {
manager = new TransientWindowManager(window);
window->SetProperty(kPropertyKey, manager);
}
return manager;
}
const TransientWindowManager* TransientWindowManager::Get(
const Window* window) {
return window->GetProperty(kPropertyKey);
}
void TransientWindowManager::AddObserver(TransientWindowObserver* observer) {
observers_.AddObserver(observer);
}
void TransientWindowManager::RemoveObserver(TransientWindowObserver* observer) {
observers_.RemoveObserver(observer);
}
void TransientWindowManager::AddTransientChild(Window* child) {
DCHECK(TransientWindowStackingClient::instance_);
TransientWindowManager* child_manager = Get(child);
if (child_manager->transient_parent_)
Get(child_manager->transient_parent_)->RemoveTransientChild(child);
DCHECK(std::find(transient_children_.begin(), transient_children_.end(),
child) == transient_children_.end());
transient_children_.push_back(child);
child_manager->transient_parent_ = window_;
FOR_EACH_OBSERVER(TransientWindowObserver, observers_,
OnTransientChildAdded(window_, child));
}
void TransientWindowManager::RemoveTransientChild(Window* child) {
Windows::iterator i =
std::find(transient_children_.begin(), transient_children_.end(), child);
DCHECK(i != transient_children_.end());
transient_children_.erase(i);
TransientWindowManager* child_manager = Get(child);
DCHECK_EQ(window_, child_manager->transient_parent_);
child_manager->transient_parent_ = NULL;
FOR_EACH_OBSERVER(TransientWindowObserver, observers_,
OnTransientChildRemoved(window_, child));
}
bool TransientWindowManager::IsStackingTransient(
const aura::Window* child,
const aura::Window* target) const {
return stacking_pair_ && stacking_pair_->child == child &&
stacking_pair_->target == target;
}
TransientWindowManager::TransientWindowManager(Window* window)
: window_(window),
transient_parent_(NULL),
stacking_pair_(NULL) {
window_->AddObserver(this);
}
void TransientWindowManager::OnChildStackingChanged(aura::Window* child) {
if (stacking_pair_ && stacking_pair_->child == child) {
Windows::const_iterator child_i = std::find(
window_->children().begin(), window_->children().end(), child);
DCHECK(child_i != window_->children().end());
if (child_i != window_->children().begin() &&
(*(child_i - 1) == stacking_pair_->target))
return;
}
Window::Windows children(window_->children());
for (Window::Windows::reverse_iterator it = children.rbegin();
it != children.rend(); ++it) {
if ((*it) != child && HasTransientAncestor(*it, child)) {
StackingPair pair(*it, child);
base::AutoReset<StackingPair*> resetter(&stacking_pair_, &pair);
window_->StackChildAbove((*it), child);
}
}
}
void TransientWindowManager::OnWindowVisibilityChanging(Window* window,
bool visible) {
if (!visible) {
std::for_each(transient_children_.begin(), transient_children_.end(),
std::mem_fun(&Window::Hide));
}
}
void TransientWindowManager::OnWindowStackingChanged(Window* window) {
TransientWindowManager* parent_manager = Get(window->parent());
parent_manager->OnChildStackingChanged(window);
}
void TransientWindowManager::OnWindowDestroying(Window* window) {
if (transient_parent_) {
TransientWindowManager::Get(transient_parent_)->RemoveTransientChild(
window_);
}
Windows transient_children(transient_children_);
STLDeleteElements(&transient_children);
DCHECK(transient_children_.empty());
}
}