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

Side by Side Diff: ui/views/widget/widget_mac_utils.mm

Issue 1796773003: Implement NativeWidgetMac::ReorderNativeViews (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implement NativeWidgetMac::ReorderNativeViews Created 4 years, 9 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
« no previous file with comments | « ui/views/widget/widget_mac_utils.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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/widget/widget_mac_utils.h"
6
7 #import <objc/runtime.h>
8
9 #include <vector>
10
11 #include "base/mac/foundation_util.h"
12 #include "ui/views/cocoa/bridged_content_view.h"
13 #include "ui/views/controls/native/native_view_host.h"
14 #include "ui/views/widget/widget.h"
15
16 namespace views {
17 namespace {
18
19 using HostedViews = std::vector<std::pair<const views::View*, NSView*>>;
20
21 struct EqualToView {
22 EqualToView(const views::View* view) : view_(view) {}
23 bool operator()(const HostedViews::value_type& v) const {
24 return v.first == view_;
25 }
26
27 private:
28 const views::View* view_;
29 };
30
31 struct EqualToNSView {
32 EqualToNSView(NSView* native_view) : native_view_(native_view) {}
33 bool operator()(const HostedViews::value_type& v) const {
34 return v.second == native_view_;
35 }
36
37 private:
38 NSView* native_view_;
39 };
40
41 HostedViews GetViewsWithAssociatedNativeViews(const Widget* widget) {
42 HostedViews result;
43 const auto* subviews = [widget->GetNativeView() subviews];
44 for (NSView* child in subviews) {
45 NSValue* value = objc_getAssociatedObject(child, &kAssociatedViewHostKey);
46 if (value)
47 result.emplace_back(static_cast<const views::View*>(value.pointerValue),
48 child);
49 }
50 return result;
51 }
52
53 HostedViews::iterator SortViewsList(const views::View* view,
54 HostedViews::iterator begin,
55 HostedViews::iterator end) {
56 auto it = std::find_if(begin, end, EqualToView(view));
57 if (it != end) {
58 std::swap(*begin, *it);
59 ++begin;
60 }
61 for (int i = 0; i < view->child_count(); ++i)
62 begin = SortViewsList(view->child_at(i), begin, end);
63 return begin;
64 }
65
66 NSComparisonResult SubviewSorter(id lhs, id rhs, void* hosts_as_void) {
67 DCHECK_NE(lhs, rhs);
68
69 const HostedViews* hosts = static_cast<const HostedViews*>(hosts_as_void);
70 auto left_it = std::find_if(hosts->begin(), hosts->end(), EqualToNSView(lhs));
tapted 2016/03/15 22:54:53 This call is O(n) so it makes the sorting algorith
kirr 2016/03/16 09:16:34 I used vector of pairs as one container for all (a
kirr 2016/03/16 21:43:45 Done.
71 auto right_it =
72 std::find_if(hosts->begin(), hosts->end(), EqualToNSView(rhs));
73 bool left_found = left_it != hosts->end();
74 bool right_found = right_it != hosts->end();
75
76 // Sort unassociated views below associated views.
77 if (left_found != right_found) {
tapted 2016/03/15 22:54:53 nit: doesn't need curlies
kirr 2016/03/16 21:43:45 Done.
78 return left_found ? NSOrderedDescending : NSOrderedAscending;
79 }
80
81 if (left_found)
tapted 2016/03/15 22:54:53 nit: needs curlies
kirr 2016/03/16 21:43:45 Done.
82 return std::distance(hosts->begin(), left_it) <
83 std::distance(hosts->begin(), right_it)
84 ? NSOrderedAscending
85 : NSOrderedDescending;
86
87 // If both are unassociated, consider that order is not important
88 return NSOrderedSame;
89 }
90
91 } // namespace
92
93 int kAssociatedViewHostKey;
94
95 void AttachNSViewRelatedToHost(NSView* native_view, NativeViewHost* host) {
tapted 2016/03/15 22:54:53 I don't think this function is necessary. Aura ob
kirr 2016/03/16 21:43:45 Done.
96 Widget* new_parent = host->GetWidget();
97 HostedViews hosts = GetViewsWithAssociatedNativeViews(new_parent);
98 hosts.emplace_back(host, native_view);
99 SortViewsList(new_parent->GetRootView(), hosts.begin(), hosts.end());
100
101 BridgedContentView* new_superview =
102 base::mac::ObjCCastStrict<BridgedContentView>(
103 new_parent->GetNativeView());
104 DCHECK(new_superview);
105
106 auto it = std::find_if(hosts.begin(), hosts.end(), EqualToView(host));
107 if (it == hosts.end() || (it + 1) == hosts.end()) {
108 [new_superview addSubview:native_view];
109 } else {
110 NSView* view_above = (it + 1)->second;
111 [new_superview addSubview:native_view
112 positioned:NSWindowBelow
113 relativeTo:view_above];
114 }
115 }
116
117 void ReorderChildNSViews(Widget* widget) {
118 HostedViews hosts = GetViewsWithAssociatedNativeViews(widget);
119 HostedViews sorted_hosts = hosts;
120 SortViewsList(widget->GetRootView(), sorted_hosts.begin(),
121 sorted_hosts.end());
122
123 if (hosts != sorted_hosts)
tapted 2016/03/15 22:54:53 nit: need curlies (policy is if the body is multi
kirr 2016/03/16 21:43:45 Done. Thanks.
124 [widget->GetNativeView() sortSubviewsUsingFunction:&SubviewSorter
tapted 2016/03/15 22:54:53 If we are worried about using this function in par
kirr 2016/03/16 21:43:45 Seems like it's better not worry about it until we
125 context:&sorted_hosts];
126 }
127
128 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/widget_mac_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698