Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: chrome/views/tree_view.cc

Issue 28175: Adds ability for tree model to reorder its children. I'm going to use... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/views/tree_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/views/tree_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698