OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/views/tree_view.h" | 5 #include "chrome/views/tree_view.h" |
6 | 6 |
7 #include <shellapi.h> | 7 #include <shellapi.h> |
8 | 8 |
9 #include "base/win_util.h" | 9 #include "base/win_util.h" |
10 #include "chrome/common/gfx/chrome_canvas.h" | 10 #include "chrome/common/gfx/chrome_canvas.h" |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 model_->GetChild(parent, i + start)); | 232 model_->GetChild(parent, i + start)); |
233 } | 233 } |
234 } | 234 } |
235 } | 235 } |
236 | 236 |
237 void TreeView::TreeNodesRemoved(TreeModel* model, | 237 void TreeView::TreeNodesRemoved(TreeModel* model, |
238 TreeModelNode* parent, | 238 TreeModelNode* parent, |
239 int start, | 239 int start, |
240 int count) { | 240 int count) { |
241 DCHECK(parent && start >= 0 && count > 0); | 241 DCHECK(parent && start >= 0 && count > 0); |
242 if (node_to_details_map_.find(parent) == node_to_details_map_.end()) { | 242 HTREEITEM parent_tree_item = GetTreeItemForNodeDuringMutation(parent); |
243 // User hasn't navigated to this entry yet. Ignore the change. | 243 if (!parent_tree_item) |
244 return; | 244 return; |
245 } | 245 |
246 HTREEITEM parent_tree_item = NULL; | |
247 if (!root_shown_ || parent != model_->GetRoot()) { | |
248 const NodeDetails* details = GetNodeDetails(parent); | |
249 if (!details->loaded_children) { | |
250 // Ignore the change, we haven't actually created entries in the tree | |
251 // for the children. | |
252 return; | |
253 } | |
254 parent_tree_item = details->tree_item; | |
255 } else { | |
256 parent_tree_item = TreeView_GetRoot(tree_view_); | |
257 } | |
258 // Find the last item. Windows doesn't offer a convenient way to get the | 246 // Find the last item. Windows doesn't offer a convenient way to get the |
259 // TREEITEM at a particular index, so we iterate. | 247 // TREEITEM at a particular index, so we iterate. |
260 HTREEITEM tree_item = TreeView_GetChild(tree_view_, parent_tree_item); | 248 HTREEITEM tree_item = TreeView_GetChild(tree_view_, parent_tree_item); |
261 for (int i = 0; i < (start + count - 1); ++i) { | 249 for (int i = 0; i < (start + count - 1); ++i) { |
262 tree_item = TreeView_GetNextSibling(tree_view_, tree_item); | 250 tree_item = TreeView_GetNextSibling(tree_view_, tree_item); |
263 } | 251 } |
264 // NOTE: the direction doesn't matter here. I've made it backwards to | 252 // NOTE: the direction doesn't matter here. I've made it backwards to |
265 // reinforce we're deleting from the end forward. | 253 // reinforce we're deleting from the end forward. |
266 for (int i = count - 1; i >= 0; --i) { | 254 for (int i = count - 1; i >= 0; --i) { |
267 HTREEITEM previous = (start + i) > 0 ? | 255 HTREEITEM previous = (start + i) > 0 ? |
268 TreeView_GetPrevSibling(tree_view_, tree_item) : NULL; | 256 TreeView_GetPrevSibling(tree_view_, tree_item) : NULL; |
269 RecursivelyDelete(GetNodeDetailsByTreeItem(tree_item)); | 257 RecursivelyDelete(GetNodeDetailsByTreeItem(tree_item)); |
270 tree_item = previous; | 258 tree_item = previous; |
271 } | 259 } |
272 } | 260 } |
273 | 261 |
| 262 namespace { |
| 263 |
| 264 // Callback function used to compare two items. The first two args are the |
| 265 // LPARAMs of the HTREEITEMs being compared. The last arg maps from LPARAM |
| 266 // to order. This is invoked from TreeNodeChildrenReordered. |
| 267 int CALLBACK CompareTreeItems(LPARAM item1_lparam, |
| 268 LPARAM item2_lparam, |
| 269 LPARAM map_as_lparam) { |
| 270 std::map<int, int>& mapping = |
| 271 *reinterpret_cast<std::map<int, int>*>(map_as_lparam); |
| 272 return mapping[static_cast<int>(item1_lparam)] - |
| 273 mapping[static_cast<int>(item2_lparam)]; |
| 274 } |
| 275 |
| 276 } // namespace |
| 277 |
| 278 void TreeView::TreeNodeChildrenReordered(TreeModel* model, |
| 279 TreeModelNode* parent) { |
| 280 DCHECK(parent); |
| 281 if (model_->GetChildCount(parent) <= 1) |
| 282 return; |
| 283 |
| 284 TVSORTCB sort_details; |
| 285 sort_details.hParent = GetTreeItemForNodeDuringMutation(parent); |
| 286 if (!sort_details.hParent) |
| 287 return; |
| 288 |
| 289 std::map<int, int> lparam_to_order_map; |
| 290 for (int i = 0; i < model_->GetChildCount(parent); ++i) { |
| 291 TreeModelNode* node = model_->GetChild(parent, i); |
| 292 lparam_to_order_map[GetNodeDetails(node)->id] = i; |
| 293 } |
| 294 |
| 295 sort_details.lpfnCompare = &CompareTreeItems; |
| 296 sort_details.lParam = reinterpret_cast<LPARAM>(&lparam_to_order_map); |
| 297 TreeView_SortChildrenCB(tree_view_, &sort_details, 0); |
| 298 } |
| 299 |
274 void TreeView::TreeNodeChanged(TreeModel* model, TreeModelNode* node) { | 300 void TreeView::TreeNodeChanged(TreeModel* model, TreeModelNode* node) { |
275 if (node_to_details_map_.find(node) == node_to_details_map_.end()) { | 301 if (node_to_details_map_.find(node) == node_to_details_map_.end()) { |
276 // User hasn't navigated to this entry yet. Ignore the change. | 302 // User hasn't navigated to this entry yet. Ignore the change. |
277 return; | 303 return; |
278 } | 304 } |
279 const NodeDetails* details = GetNodeDetails(node); | 305 const NodeDetails* details = GetNodeDetails(node); |
280 TV_ITEM tv_item = {0}; | 306 TV_ITEM tv_item = {0}; |
281 tv_item.mask = TVIF_TEXT; | 307 tv_item.mask = TVIF_TEXT; |
282 tv_item.hItem = details->tree_item; | 308 tv_item.hItem = details->tree_item; |
283 tv_item.pszText = LPSTR_TEXTCALLBACK; | 309 tv_item.pszText = LPSTR_TEXTCALLBACK; |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 DestroyIcon(h_opened_icon); | 641 DestroyIcon(h_opened_icon); |
616 for (size_t i = 0; i < model_images.size(); ++i) { | 642 for (size_t i = 0; i < model_images.size(); ++i) { |
617 HICON model_icon = IconUtil::CreateHICONFromSkBitmap(model_images[i]); | 643 HICON model_icon = IconUtil::CreateHICONFromSkBitmap(model_images[i]); |
618 ImageList_AddIcon(image_list, model_icon); | 644 ImageList_AddIcon(image_list, model_icon); |
619 DestroyIcon(model_icon); | 645 DestroyIcon(model_icon); |
620 } | 646 } |
621 } | 647 } |
622 return image_list; | 648 return image_list; |
623 } | 649 } |
624 | 650 |
| 651 HTREEITEM TreeView::GetTreeItemForNodeDuringMutation(TreeModelNode* node) { |
| 652 if (node_to_details_map_.find(node) == node_to_details_map_.end()) { |
| 653 // User hasn't navigated to this entry yet. Ignore the change. |
| 654 return NULL; |
| 655 } |
| 656 if (!root_shown_ || node != model_->GetRoot()) { |
| 657 const NodeDetails* details = GetNodeDetails(node); |
| 658 if (!details->loaded_children) |
| 659 return NULL; |
| 660 return details->tree_item; |
| 661 } |
| 662 return TreeView_GetRoot(tree_view_); |
| 663 } |
| 664 |
625 LRESULT CALLBACK TreeView::TreeWndProc(HWND window, | 665 LRESULT CALLBACK TreeView::TreeWndProc(HWND window, |
626 UINT message, | 666 UINT message, |
627 WPARAM w_param, | 667 WPARAM w_param, |
628 LPARAM l_param) { | 668 LPARAM l_param) { |
629 TreeViewWrapper* wrapper = reinterpret_cast<TreeViewWrapper*>( | 669 TreeViewWrapper* wrapper = reinterpret_cast<TreeViewWrapper*>( |
630 GetWindowLongPtr(window, GWLP_USERDATA)); | 670 GetWindowLongPtr(window, GWLP_USERDATA)); |
631 DCHECK(wrapper); | 671 DCHECK(wrapper); |
632 TreeView* tree = wrapper->tree_view; | 672 TreeView* tree = wrapper->tree_view; |
633 | 673 |
634 // We handle the messages WM_ERASEBKGND and WM_PAINT such that we paint into | 674 // We handle the messages WM_ERASEBKGND and WM_PAINT such that we paint into |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 734 } |
695 // Fall through and let the default handler process as well. | 735 // Fall through and let the default handler process as well. |
696 break; | 736 break; |
697 } | 737 } |
698 WNDPROC handler = tree->original_handler_; | 738 WNDPROC handler = tree->original_handler_; |
699 DCHECK(handler); | 739 DCHECK(handler); |
700 return CallWindowProc(handler, window, message, w_param, l_param); | 740 return CallWindowProc(handler, window, message, w_param, l_param); |
701 } | 741 } |
702 | 742 |
703 } // namespace views | 743 } // namespace views |
OLD | NEW |