Chromium Code Reviews| Index: chrome/browser/views/bookmark_folder_tree_view.cc |
| =================================================================== |
| --- chrome/browser/views/bookmark_folder_tree_view.cc (revision 4555) |
| +++ chrome/browser/views/bookmark_folder_tree_view.cc (working copy) |
| @@ -11,10 +11,14 @@ |
| #include "chrome/browser/profile.h" |
| #include "chrome/common/drag_drop_types.h" |
| #include "chrome/common/os_exchange_data.h" |
| -#include "chrome/views/chrome_menu.h" |
| +#include "chrome/views/view_constants.h" |
| #include "generated_resources.h" |
| +void BookmarkFolderTreeView::DropInfo::Scrolled() { |
| + view_->UpdateDropInfo(); |
| +} |
| + |
| BookmarkFolderTreeView::BookmarkFolderTreeView(Profile* profile, |
| BookmarkFolderTreeModel* model) |
| : views::TreeView(), |
| @@ -30,14 +34,18 @@ |
| if (!profile_->GetBookmarkModel()->IsLoaded()) |
| return false; |
| - drop_info_.reset(new DropInfo()); |
| - if (!drop_info_->drag_data.Read(data)) |
| + BookmarkDragData drag_data; |
| + |
| + if (!drag_data.Read(data)) |
| return false; |
| + drop_info_.reset(new DropInfo(this)); |
| + drop_info_->SetData(drag_data); |
| + |
| // See if there are any urls being dropped. |
| - for (size_t i = 0; i < drop_info_->drag_data.size(); ++i) { |
| - if (drop_info_->drag_data.elements[0].is_url) { |
| - drop_info_->only_folders = false; |
| + for (size_t i = 0; i < drop_info_->data().size(); ++i) { |
| + if (drop_info_->data().elements[0].is_url) { |
| + drop_info_->set_only_folders(false); |
| break; |
| } |
| } |
| @@ -50,27 +58,12 @@ |
| } |
| int BookmarkFolderTreeView::OnDragUpdated(const views::DropTargetEvent& event) { |
| - int drop_index; |
| - bool drop_on; |
| - FolderNode* drop_parent = |
| - CalculateDropParent(event.y(), drop_info_->only_folders, &drop_index, |
| - &drop_on); |
| - drop_info_->drop_operation = |
| - CalculateDropOperation(event, drop_parent, drop_index, drop_on); |
| - |
| - if (drop_info_->drop_operation == DragDropTypes::DRAG_NONE) { |
| - drop_parent = NULL; |
| - drop_index = -1; |
| - drop_on = false; |
| - } |
| - |
| - SetDropParent(drop_parent, drop_index, drop_on); |
| - |
| - return drop_info_->drop_operation; |
| + drop_info_->Update(event); |
| + return UpdateDropInfo(); |
| } |
| void BookmarkFolderTreeView::OnDragExited() { |
| - SetDropParent(NULL, -1, false); |
| + SetDropPosition(DropPosition()); |
| drop_info_.reset(); |
| } |
| @@ -78,8 +71,8 @@ |
| int BookmarkFolderTreeView::OnPerformDrop(const views::DropTargetEvent& event) { |
| OnPerformDropImpl(); |
| - int drop_operation = drop_info_->drop_operation; |
| - SetDropParent(NULL, -1, false); |
| + int drop_operation = drop_info_->drop_operation(); |
| + SetDropPosition(DropPosition()); |
| drop_info_.reset(); |
| return drop_operation; |
| } |
| @@ -106,6 +99,19 @@ |
| return TreeView::OnNotify(w_param, l_param); |
| } |
| +int BookmarkFolderTreeView::UpdateDropInfo() { |
| + DropPosition position = |
| + CalculateDropPosition(drop_info_->last_y(), drop_info_->only_folders()); |
| + drop_info_->set_drop_operation(CalculateDropOperation(position)); |
| + |
| + if (drop_info_->drop_operation() == DragDropTypes::DRAG_NONE) |
| + position = DropPosition(); |
| + |
| + SetDropPosition(position); |
| + |
| + return drop_info_->drop_operation(); |
| +} |
| + |
| void BookmarkFolderTreeView::BeginDrag(BookmarkNode* node) { |
| BookmarkModel* model = profile_->GetBookmarkModel(); |
| // Only allow the drag if the user has selected a node of type bookmark and it |
| @@ -128,12 +134,8 @@ |
| is_dragging_ = false; |
| } |
| -FolderNode* BookmarkFolderTreeView::CalculateDropParent(int y, |
| - bool only_folders, |
| - int* drop_index, |
| - bool* drop_on) { |
| - *drop_on = false; |
| - *drop_index = -1; |
| +BookmarkFolderTreeView::DropPosition BookmarkFolderTreeView:: |
|
ncarter (slow)
2008/11/04 18:39:47
Is the first scope resolution necessary?
|
| + CalculateDropPosition(int y, bool only_folders) { |
| HWND hwnd = GetNativeControlHWND(); |
| HTREEITEM item = TreeView_GetFirstVisible(hwnd); |
| while (item) { |
| @@ -144,7 +146,7 @@ |
| if (folder_model()->GetNodeType(model_node) != |
| BookmarkFolderTreeModel::BOOKMARK) { |
| // Only allow drops on bookmark nodes. |
| - return NULL; |
| + return DropPosition(); |
| } |
| FolderNode* node = folder_model()->AsNode(model_node); |
| @@ -153,59 +155,52 @@ |
| // If some of the elements being dropped are urls, then we only allow |
| // dropping on a folder. Similarly you can't drop between the |
| // bookmark bar and other folder nodes. |
| - *drop_on = true; |
| - *drop_index = node->GetChildCount(); |
| - return node; |
| + return DropPosition(node, node->GetChildCount(), true); |
| } |
| // Drop contains all folders, allow them to be dropped between |
| // folders. |
| - if (y < bounds.top + views::MenuItemView::kDropBetweenPixels) { |
| - *drop_index = node->GetParent()->IndexOfChild(node); |
| - return node->GetParent(); |
| + if (y < bounds.top + views::kDropBetweenPixels) { |
| + return DropPosition(node->GetParent(), |
| + node->GetParent()->IndexOfChild(node), false); |
| } |
| - if (y >= bounds.bottom - views::MenuItemView::kDropBetweenPixels) { |
| + if (y >= bounds.bottom - views::kDropBetweenPixels) { |
| if (IsExpanded(node) && folder_model()->GetChildCount(node) > 0) { |
| // The node is expanded and has children, treat the drop as occurring |
| // as the first child. This is done to avoid the selection highlight |
| // dancing around when dragging over expanded folders. Without this |
| // the highlight jumps past the last expanded child of node. |
| - *drop_index = 0; |
| - return node; |
| + return DropPosition(node, 0, false); |
| } |
| - *drop_index = node->GetParent()->IndexOfChild(node) + 1; |
| - return node->GetParent(); |
| + return DropPosition(node->GetParent(), |
| + node->GetParent()->IndexOfChild(node) + 1, false); |
| } |
| - *drop_on = true; |
| - *drop_index = node->GetChildCount(); |
| - return node; |
| + return DropPosition(node, node->GetChildCount(), true); |
| } |
| item = TreeView_GetNextVisible(hwnd, item); |
| } |
| - return NULL; |
| + return DropPosition(); |
| } |
| int BookmarkFolderTreeView::CalculateDropOperation( |
| - const views::DropTargetEvent& event, |
| - FolderNode* drop_parent, |
| - int drop_index, |
| - bool drop_on) { |
| - if (!drop_parent) |
| + const DropPosition& position) { |
| + if (!position.parent) |
| return DragDropTypes::DRAG_NONE; |
| - if (drop_info_->drag_data.IsFromProfile(profile_)) { |
| + if (drop_info_->data().IsFromProfile(profile_)) { |
| int bookmark_model_drop_index = |
| - FolderIndexToBookmarkIndex(drop_parent, drop_index, drop_on); |
| + FolderIndexToBookmarkIndex(position.parent, position.index, |
| + position.on); |
| if (!bookmark_utils::IsValidDropLocation( |
| - profile_, drop_info_->drag_data, |
| - TreeNodeAsBookmarkNode(drop_parent), |
| + profile_, drop_info_->data(), |
| + TreeNodeAsBookmarkNode(position.parent), |
| bookmark_model_drop_index)) { |
| return DragDropTypes::DRAG_NONE; |
| } |
| // Data from the same profile. Prefer move, but do copy if the user wants |
| // that. |
| - if (event.IsControlDown()) |
| + if (drop_info_->is_control_down()) |
| return DragDropTypes::DRAG_COPY; |
| return DragDropTypes::DRAG_MOVE; |
| @@ -213,25 +208,28 @@ |
| // We're going to copy, but return an operation compatible with the source |
| // operations so that the user can drop. |
| return bookmark_utils::PreferredDropOperation( |
| - event, DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); |
| + drop_info_->source_operations(), |
| + DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); |
| } |
| void BookmarkFolderTreeView::OnPerformDropImpl() { |
| - BookmarkNode* parent_node = TreeNodeAsBookmarkNode(drop_info_->drop_parent); |
| + BookmarkNode* parent_node = |
| + TreeNodeAsBookmarkNode(drop_info_->position().parent); |
| int drop_index = FolderIndexToBookmarkIndex( |
| - drop_info_->drop_parent, drop_info_->drop_index, drop_info_->drop_on); |
| + drop_info_->position().parent, drop_info_->position().index, |
| + drop_info_->position().on); |
| BookmarkModel* model = profile_->GetBookmarkModel(); |
| // If the data is not from this profile we return an operation compatible |
| // with the source. As such, we need to need to check the data here too. |
| - if (!drop_info_->drag_data.IsFromProfile(profile_) || |
| - drop_info_->drop_operation == DragDropTypes::DRAG_COPY) { |
| - bookmark_utils::CloneDragData(model, drop_info_->drag_data.elements, |
| + if (!drop_info_->data().IsFromProfile(profile_) || |
| + drop_info_->drop_operation() == DragDropTypes::DRAG_COPY) { |
| + bookmark_utils::CloneDragData(model, drop_info_->data().elements, |
| parent_node, drop_index); |
| return; |
| } |
| // else, move. |
| - std::vector<BookmarkNode*> nodes = drop_info_->drag_data.GetNodes(profile_); |
| + std::vector<BookmarkNode*> nodes = drop_info_->data().GetNodes(profile_); |
| if (nodes.empty()) |
| return; |
| @@ -250,46 +248,36 @@ |
| } |
| } |
| -void BookmarkFolderTreeView::SetDropParent(FolderNode* node, |
| - int drop_index, |
| - bool drop_on) { |
| - if (drop_info_->drop_parent == node && |
| - drop_info_->drop_index == drop_index && |
| - drop_info_->drop_on == drop_on) { |
| +void BookmarkFolderTreeView::SetDropPosition(const DropPosition& position) { |
| + if (drop_info_->position().equals(position)) |
| return; |
| - } |
| + |
| // Remove the indicator over the previous location. |
| - if (drop_info_->drop_on) { |
| - HTREEITEM item = GetTreeItemForNode(drop_info_->drop_parent); |
| + if (drop_info_->position().on) { |
| + HTREEITEM item = GetTreeItemForNode(drop_info_->position().parent); |
| if (item) |
| TreeView_SetItemState(GetNativeControlHWND(), item, 0, TVIS_DROPHILITED); |
| - } else if (drop_info_->drop_index != -1) { |
| + } else if (drop_info_->position().index != -1) { |
| TreeView_SetInsertMark(GetNativeControlHWND(), NULL, FALSE); |
| } |
| - drop_info_->drop_parent = node; |
| - drop_info_->drop_index = drop_index; |
| - drop_info_->drop_on = drop_on; |
| + drop_info_->set_position(position); |
| // And show the new indicator. |
| - if (drop_info_->drop_on) { |
| - HTREEITEM item = GetTreeItemForNode(drop_info_->drop_parent); |
| + if (position.on) { |
| + HTREEITEM item = GetTreeItemForNode(position.parent); |
| if (item) { |
| TreeView_SetItemState(GetNativeControlHWND(), item, TVIS_DROPHILITED, |
| TVIS_DROPHILITED); |
| } |
| - } else if (drop_info_->drop_index != -1) { |
| + } else if (position.index != -1) { |
| BOOL after = FALSE; |
| - if (folder_model()->GetChildCount(drop_info_->drop_parent) == |
| - drop_info_->drop_index) { |
| + FolderNode* node = position.parent; |
| + if (folder_model()->GetChildCount(position.parent) == position.index) { |
| after = TRUE; |
| - node = |
| - folder_model()->GetChild(drop_info_->drop_parent, |
| - drop_info_->drop_index - 1); |
| + node = folder_model()->GetChild(position.parent, position.index - 1); |
| } else { |
| - node = |
| - folder_model()->GetChild(drop_info_->drop_parent, |
| - drop_info_->drop_index); |
| + node = folder_model()->GetChild(position.parent, position.index); |
| } |
| HTREEITEM item = GetTreeItemForNode(node); |
| if (item) |