void BaseTabStrip::StartedDraggingTabs(const std::vector<BaseTab*>& tabs) { PrepareForAnimation(); // Reset dragging state of existing tabs. for(int i=0; i<tab_count(); ++i) { base_tab_at_tab_index(i)->set_dragging(false); } for(size_t i=0; i<tabs.size(); ++i) { tabs[i]->set_dragging(true); bounds_animator_.StopAnimatingView(tabs[i]); } // Move the dragged tabs to their ideal bounds. GenerateIdealBounds(); // Sets the bounds of the dragged tabs. for(size_t i=0; i<tabs.size(); ++i) { int tab_data_index = TabIndexOfTab(tabs[i]); DCHECK(tab_data_index != -1); tabs[i]->SetBoundsRect(ideal_bounds(tab_data_index)); } SchedulePaint(); }
void TabWidget::add_tab(int index, const std::string &label, Widget *tab) { assert(index <= tab_count()); // It is important to add the content first since the callback // of the header will automatically fire when a new tab is added. m_content->add_child(index, tab); m_header->add_tab(index, label); assert(m_header->tab_count() == m_content->child_count()); }
void BaseTabStrip::PrepareForAnimation() { if(!IsDragSessionActive() && !DraggedTabController::IsAttachedTo(this)) { for(int i=0; i<tab_count(); ++i) { base_tab_at_tab_index(i)->set_dragging(false); } } }
int BaseTabStrip::TabIndexOfTab(BaseTab* tab) const { for(int i=0; i<tab_count(); ++i) { if(base_tab_at_tab_index(i) == tab) { return i; } } return -1; }
bool BaseTabStrip::IsActiveDropTarget() const { for(int i=0; i<tab_count(); ++i) { BaseTab* tab = base_tab_at_tab_index(i); if(tab->dragging()) { return true; } } return false; }
void BaseTabStrip::MaybeStartDrag(BaseTab* tab, const view::MouseEvent& event) { // Don't accidentally start any drag operations during animations if the // mouse is down... during an animation tabs are being resized automatically, // so the View system can misinterpret this easily if the mouse is down that // the user is dragging. if(IsAnimating() || tab->closing() || controller_->HasAvailableDragActions()==0) { return; } int model_index = GetModelIndexOfBaseTab(tab); if(!IsValidModelIndex(model_index)) { CHECK(false); return; } drag_controller_.reset(new DraggedTabController()); std::vector<BaseTab*> tabs; int size_to_selected = 0; int x = tab->GetMirroredXInView(event.x()); int y = event.y(); // Build the set of selected tabs to drag and calculate the offset from the // first selected tab. for(int i=0; i<tab_count(); ++i) { BaseTab* other_tab = base_tab_at_tab_index(i); if(IsTabSelected(other_tab) && !other_tab->closing()) { tabs.push_back(other_tab); if(other_tab == tab) { size_to_selected = GetSizeNeededForTabs(tabs); if(type() == HORIZONTAL_TAB_STRIP) { x = size_to_selected - tab->width() + x; } else { y = size_to_selected - tab->height() + y; } } } } DCHECK(!tabs.empty()); DCHECK(std::find(tabs.begin(), tabs.end(), tab) != tabs.end()); drag_controller_->Init(this, tab, tabs, gfx::Point(x, y), tab->GetMirroredXInView(event.x())); }
void BaseTabStrip::DoLayout() { last_layout_size_ = size(); StopAnimating(false); GenerateIdealBounds(); for(int i=0; i<tab_count(); ++i) { tab_data_[i].tab->SetBoundsRect(tab_data_[i].ideal_bounds); } SchedulePaint(); }
// Overridden to support automation. See automation_proxy_uitest.cc. const view::View* BaseTabStrip::GetViewByID(int view_id) const { if(tab_count() > 0) { if(view_id == VIEW_ID_TAB_LAST) { return base_tab_at_tab_index(tab_count() - 1); } else if((view_id >= VIEW_ID_TAB_0) && (view_id < VIEW_ID_TAB_LAST)) { int index = view_id - VIEW_ID_TAB_0; if(index>=0 && index<tab_count()) { return base_tab_at_tab_index(index); } else { return NULL; } } } return View::GetViewByID(view_id); }
int BaseTabStrip::ModelIndexToTabIndex(int model_index) const { int current_model_index = 0; for(int i=0; i<tab_count(); ++i) { if(!base_tab_at_tab_index(i)->closing()) { if(current_model_index == model_index) { return i; } current_model_index++; } } return static_cast<int>(tab_data_.size()); }
int BaseTabStrip::GetModelIndexOfBaseTab(const BaseTab* tab) const { for(int i=0,model_index=0; i<tab_count(); ++i) { BaseTab* current_tab = base_tab_at_tab_index(i); if(!current_tab->closing()) { if(current_tab == tab) { return model_index; } model_index++; } else if(current_tab == tab) { return -1; } } return -1; }
void BaseTabStrip::AddTabAt(int model_index, const TabRendererData& data) { BaseTab* tab = CreateTab(); tab->SetData(data); TabData d = { tab, gfx::Rect() }; tab_data_.insert(tab_data_.begin() + ModelIndexToTabIndex(model_index), d); AddChildView(tab); // Don't animate the first tab, it looks weird, and don't animate anything // if the containing window isn't visible yet. if(tab_count()>1 && GetWidget() && GetWidget()->IsVisible()) { StartInsertTabAnimation(model_index); } else { DoLayout(); } }
void BaseTabStrip::CloseTab(BaseTab* tab) { // Find the closest model index. We do this so that the user can rapdily close // tabs and have the close click close the next tab. int model_index = 0; for(int i=0; i<tab_count(); ++i) { BaseTab* current_tab = base_tab_at_tab_index(i); if(current_tab == tab) { break; } if(!current_tab->closing()) { model_index++; } } if(IsValidModelIndex(model_index)) { controller_->CloseTab(model_index); } }
void TabWidget::add_tab(const std::string &name, Widget *tab) { add_tab(tab_count(), name, tab); }
Widget* TabWidget::create_tab(const std::string &label) { return create_tab(tab_count(), label); }