OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
6 | 6 |
7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <limits> | 10 #include <limits> |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 finished:(BOOL)finished; | 167 finished:(BOOL)finished; |
168 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 168 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
169 - (void)clickNewTabButton:(id)sender; | 169 - (void)clickNewTabButton:(id)sender; |
170 - (NSInteger)numberOfOpenTabs; | 170 - (NSInteger)numberOfOpenTabs; |
171 - (NSInteger)numberOfOpenPinnedTabs; | 171 - (NSInteger)numberOfOpenPinnedTabs; |
172 - (NSInteger)numberOfOpenNonPinnedTabs; | 172 - (NSInteger)numberOfOpenNonPinnedTabs; |
173 - (void)mouseMoved:(NSEvent*)event; | 173 - (void)mouseMoved:(NSEvent*)event; |
174 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; | 174 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; |
175 - (void)droppingURLsAt:(NSPoint)point | 175 - (void)droppingURLsAt:(NSPoint)point |
176 givesIndex:(NSInteger*)index | 176 givesIndex:(NSInteger*)index |
177 disposition:(WindowOpenDisposition*)disposition; | 177 disposition:(WindowOpenDisposition*)disposition |
178 activateTab:(BOOL)activateTab; | |
178 - (void)setNewTabButtonHoverState:(BOOL)showHover; | 179 - (void)setNewTabButtonHoverState:(BOOL)showHover; |
179 - (void)themeDidChangeNotification:(NSNotification*)notification; | 180 - (void)themeDidChangeNotification:(NSNotification*)notification; |
180 - (BOOL)doesAnyOtherWebContents:(content::WebContents*)selected | 181 - (BOOL)doesAnyOtherWebContents:(content::WebContents*)selected |
181 haveAlertState:(TabAlertState)state; | 182 haveAlertState:(TabAlertState)state; |
182 @end | 183 @end |
183 | 184 |
184 // A simple view class that contains the traffic light buttons. This class | 185 // A simple view class that contains the traffic light buttons. This class |
185 // ensures that the buttons display the icons when the mouse hovers over | 186 // ensures that the buttons display the icons when the mouse hovers over |
186 // them by overriding the _mouseInGroup method. | 187 // them by overriding the _mouseInGroup method. |
187 @interface CustomWindowControlsView : NSView { | 188 @interface CustomWindowControlsView : NSView { |
(...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2003 [tabStripView_ setSubviews:subviews]; | 2004 [tabStripView_ setSubviews:subviews]; |
2004 [self setTabTrackingAreasEnabled:mouseInside_]; | 2005 [self setTabTrackingAreasEnabled:mouseInside_]; |
2005 } | 2006 } |
2006 | 2007 |
2007 // Get the index and disposition for a potential URL(s) drop given a point (in | 2008 // Get the index and disposition for a potential URL(s) drop given a point (in |
2008 // the |TabStripView|'s coordinates). It considers only the x-coordinate of the | 2009 // the |TabStripView|'s coordinates). It considers only the x-coordinate of the |
2009 // given point. If it's in the "middle" of a tab, it drops on that tab. If it's | 2010 // given point. If it's in the "middle" of a tab, it drops on that tab. If it's |
2010 // to the left, it inserts to the left, and similarly for the right. | 2011 // to the left, it inserts to the left, and similarly for the right. |
2011 - (void)droppingURLsAt:(NSPoint)point | 2012 - (void)droppingURLsAt:(NSPoint)point |
2012 givesIndex:(NSInteger*)index | 2013 givesIndex:(NSInteger*)index |
2013 disposition:(WindowOpenDisposition*)disposition { | 2014 disposition:(WindowOpenDisposition*)disposition |
2015 activateTab:(BOOL)activateTab { | |
2014 // Proportion of the tab which is considered the "middle" (and causes things | 2016 // Proportion of the tab which is considered the "middle" (and causes things |
2015 // to drop on that tab). | 2017 // to drop on that tab). |
2016 const double kMiddleProportion = 0.5; | 2018 const double kMiddleProportion = 0.5; |
2017 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; | 2019 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; |
2018 const CGFloat kTabOverlap = [TabStripController tabOverlap]; | 2020 const CGFloat kTabOverlap = [TabStripController tabOverlap]; |
2019 | 2021 |
2020 DCHECK(index && disposition); | 2022 DCHECK(index && disposition); |
2021 NSInteger i = 0; | 2023 NSInteger i = 0; |
2022 for (TabController* tab in tabArray_.get()) { | 2024 for (TabController* tab in tabArray_.get()) { |
2023 NSView* view = [tab view]; | 2025 NSView* view = [tab view]; |
2024 DCHECK([view isKindOfClass:[TabView class]]); | 2026 DCHECK([view isKindOfClass:[TabView class]]); |
2025 | 2027 |
2026 // Recall that |-[NSView frame]| is in its superview's coordinates, so a | 2028 // Recall that |-[NSView frame]| is in its superview's coordinates, so a |
2027 // |TabView|'s frame is in the coordinates of the |TabStripView| (which | 2029 // |TabView|'s frame is in the coordinates of the |TabStripView| (which |
2028 // matches the coordinate system of |point|). | 2030 // matches the coordinate system of |point|). |
2029 NSRect frame = [view frame]; | 2031 NSRect frame = [view frame]; |
2030 | 2032 |
2031 // Modify the frame to make it "unoverlapped". | 2033 // Modify the frame to make it "unoverlapped". |
2032 frame.origin.x += kTabOverlap / 2.0; | 2034 frame.origin.x += kTabOverlap / 2.0; |
2033 frame.size.width -= kTabOverlap; | 2035 frame.size.width -= kTabOverlap; |
2034 if (frame.size.width < 1.0) | 2036 if (frame.size.width < 1.0) |
2035 frame.size.width = 1.0; // try to avoid complete failure | 2037 frame.size.width = 1.0; // try to avoid complete failure |
2036 | 2038 |
2037 // Drop in a new tab to the left of tab |i|? | 2039 // Drop in a new tab to the left of tab |i|? |
2038 if (point.x < (frame.origin.x + kLRProportion * frame.size.width)) { | 2040 if (point.x < (frame.origin.x + kLRProportion * frame.size.width)) { |
2039 *index = i; | 2041 *index = i; |
2040 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | 2042 if (activateTab) { |
2043 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | |
2044 } else { | |
2045 *disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
2046 } | |
2041 return; | 2047 return; |
2042 } | 2048 } |
2043 | 2049 |
2044 // Drop on tab |i|? | 2050 // Drop on tab |i|? |
2045 if (point.x <= (frame.origin.x + | 2051 if (point.x <= (frame.origin.x + |
2046 (1.0 - kLRProportion) * frame.size.width)) { | 2052 (1.0 - kLRProportion) * frame.size.width)) { |
2047 *index = i; | 2053 *index = i; |
2048 *disposition = WindowOpenDisposition::CURRENT_TAB; | 2054 *disposition = WindowOpenDisposition::CURRENT_TAB; |
2049 return; | 2055 return; |
2050 } | 2056 } |
2051 | 2057 |
2052 // (Dropping in a new tab to the right of tab |i| will be taken care of in | 2058 // (Dropping in a new tab to the right of tab |i| will be taken care of in |
2053 // the next iteration.) | 2059 // the next iteration.) |
2054 i++; | 2060 i++; |
2055 } | 2061 } |
2056 | 2062 |
2057 // If we've made it here, we want to append a new tab to the end. | 2063 // If we've made it here, we want to append a new tab to the end. |
2058 *index = -1; | 2064 *index = -1; |
2059 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | 2065 if (activateTab) { |
2066 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; | |
2067 } else { | |
2068 *disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; | |
2069 } | |
2060 } | 2070 } |
2061 | 2071 |
2062 - (void)openURL:(GURL*)url inView:(NSView*)view at:(NSPoint)point { | 2072 - (void)openURL:(GURL*)url |
2073 inView:(NSView*)view | |
2074 at:(NSPoint)point | |
2075 activateTab:(BOOL)activateTab { | |
2063 // Security: Block JavaScript to prevent self-XSS. | 2076 // Security: Block JavaScript to prevent self-XSS. |
2064 if (url->SchemeIs(url::kJavaScriptScheme)) | 2077 if (url->SchemeIs(url::kJavaScriptScheme)) |
2065 return; | 2078 return; |
2066 | 2079 |
2067 // Get the index and disposition. | 2080 // Get the index and disposition. |
2068 NSInteger index; | 2081 NSInteger index; |
2069 WindowOpenDisposition disposition; | 2082 WindowOpenDisposition disposition; |
2070 [self droppingURLsAt:point | 2083 [self droppingURLsAt:point |
2071 givesIndex:&index | 2084 givesIndex:&index |
2072 disposition:&disposition]; | 2085 disposition:&disposition |
2086 activateTab:activateTab]; | |
2073 | 2087 |
2074 // Either insert a new tab or open in a current tab. | 2088 // Either insert a new tab or open in a current tab. |
2075 switch (disposition) { | 2089 switch (disposition) { |
2076 case WindowOpenDisposition::NEW_FOREGROUND_TAB: { | 2090 case WindowOpenDisposition::NEW_FOREGROUND_TAB: |
2091 case WindowOpenDisposition::NEW_BACKGROUND_TAB: { | |
2077 content::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs")); | 2092 content::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs")); |
2078 chrome::NavigateParams params(browser_, *url, | 2093 chrome::NavigateParams params(browser_, *url, |
2079 ui::PAGE_TRANSITION_TYPED); | 2094 ui::PAGE_TRANSITION_TYPED); |
2080 params.disposition = disposition; | 2095 params.disposition = disposition; |
2081 params.tabstrip_index = index; | 2096 params.tabstrip_index = index; |
2082 params.tabstrip_add_types = | 2097 params.tabstrip_add_types = |
2083 TabStripModel::ADD_ACTIVE | TabStripModel::ADD_FORCE_INDEX; | 2098 TabStripModel::ADD_ACTIVE | TabStripModel::ADD_FORCE_INDEX; |
2084 chrome::Navigate(¶ms); | 2099 chrome::Navigate(¶ms); |
2085 break; | 2100 break; |
2086 } | 2101 } |
(...skipping 12 matching lines...) Expand all Loading... | |
2099 | 2114 |
2100 // (URLDropTargetController protocol) | 2115 // (URLDropTargetController protocol) |
2101 - (void)dropURLs:(NSArray*)urls inView:(NSView*)view at:(NSPoint)point { | 2116 - (void)dropURLs:(NSArray*)urls inView:(NSView*)view at:(NSPoint)point { |
2102 DCHECK_EQ(view, tabStripView_.get()); | 2117 DCHECK_EQ(view, tabStripView_.get()); |
2103 | 2118 |
2104 if ([urls count] < 1) { | 2119 if ([urls count] < 1) { |
2105 NOTREACHED(); | 2120 NOTREACHED(); |
2106 return; | 2121 return; |
2107 } | 2122 } |
2108 | 2123 |
2109 //TODO(viettrungluu): dropping multiple URLs. | 2124 for (NSInteger index = [urls count] - 1; index >= 0; index--) { |
erikchen
2016/11/22 22:52:25
Comparison against 0 is fine, you just need to use
| |
2110 if ([urls count] > 1) | 2125 // Refactor this code. |
2111 NOTIMPLEMENTED(); | 2126 // https://crbug.com/665261. |
2127 GURL url = url_formatter::FixupURL( | |
2128 base::SysNSStringToUTF8([urls objectAtIndex:index]), std::string()); | |
2112 | 2129 |
2113 // Get the first URL and fix it up. | 2130 // If the URL isn't valid, don't bother. |
2114 GURL url(GURL(url_formatter::FixupURL( | 2131 if (!url.is_valid()) |
2115 base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string()))); | 2132 continue; |
2116 | 2133 |
2117 // If the URL isn't valid, don't bother. | 2134 if (index == static_cast<NSInteger>([urls count]) - 1) { |
2118 if (!url.is_valid()) | 2135 [self openURL:&url inView:view at:point activateTab:YES]; |
2119 return; | 2136 } else { |
2120 | 2137 [self openURL:&url inView:view at:point activateTab:NO]; |
2121 [self openURL:&url inView:view at:point]; | 2138 } |
2139 } | |
2122 } | 2140 } |
2123 | 2141 |
2124 // (URLDropTargetController protocol) | 2142 // (URLDropTargetController protocol) |
2125 - (void)dropText:(NSString*)text inView:(NSView*)view at:(NSPoint)point { | 2143 - (void)dropText:(NSString*)text inView:(NSView*)view at:(NSPoint)point { |
2126 DCHECK_EQ(view, tabStripView_.get()); | 2144 DCHECK_EQ(view, tabStripView_.get()); |
2127 | 2145 |
2128 // If the input is plain text, classify the input and make the URL. | 2146 // If the input is plain text, classify the input and make the URL. |
2129 AutocompleteMatch match; | 2147 AutocompleteMatch match; |
2130 AutocompleteClassifierFactory::GetForProfile(browser_->profile())->Classify( | 2148 AutocompleteClassifierFactory::GetForProfile(browser_->profile())->Classify( |
2131 base::SysNSStringToUTF16(text), false, false, | 2149 base::SysNSStringToUTF16(text), false, false, |
2132 metrics::OmniboxEventProto::BLANK, &match, NULL); | 2150 metrics::OmniboxEventProto::BLANK, &match, NULL); |
2133 GURL url(match.destination_url); | 2151 GURL url(match.destination_url); |
2134 | 2152 |
2135 [self openURL:&url inView:view at:point]; | 2153 [self openURL:&url inView:view at:point activateTab:YES]; |
2136 } | 2154 } |
2137 | 2155 |
2138 // (URLDropTargetController protocol) | 2156 // (URLDropTargetController protocol) |
2139 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { | 2157 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { |
2140 DCHECK_EQ(view, tabStripView_.get()); | 2158 DCHECK_EQ(view, tabStripView_.get()); |
2141 | 2159 |
2142 // The minimum y-coordinate at which one should consider place the arrow. | 2160 // The minimum y-coordinate at which one should consider place the arrow. |
2143 const CGFloat arrowBaseY = 25; | 2161 const CGFloat arrowBaseY = 25; |
2144 const CGFloat kTabOverlap = [TabStripController tabOverlap]; | 2162 const CGFloat kTabOverlap = [TabStripController tabOverlap]; |
2145 | 2163 |
2146 NSInteger index; | 2164 NSInteger index; |
2147 WindowOpenDisposition disposition; | 2165 WindowOpenDisposition disposition; |
2148 [self droppingURLsAt:point | 2166 [self droppingURLsAt:point |
2149 givesIndex:&index | 2167 givesIndex:&index |
2150 disposition:&disposition]; | 2168 disposition:&disposition |
2169 activateTab:YES]; | |
2151 | 2170 |
2152 NSPoint arrowPos = NSMakePoint(0, arrowBaseY); | 2171 NSPoint arrowPos = NSMakePoint(0, arrowBaseY); |
2153 if (index == -1) { | 2172 if (index == -1) { |
2154 // Append a tab at the end. | 2173 // Append a tab at the end. |
2155 DCHECK(disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB); | 2174 DCHECK(disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB); |
2156 NSInteger lastIndex = [tabArray_ count] - 1; | 2175 NSInteger lastIndex = [tabArray_ count] - 1; |
2157 NSRect overRect = [[[tabArray_ objectAtIndex:lastIndex] view] frame]; | 2176 NSRect overRect = [[[tabArray_ objectAtIndex:lastIndex] view] frame]; |
2158 arrowPos.x = overRect.origin.x + overRect.size.width - kTabOverlap / 2.0; | 2177 arrowPos.x = overRect.origin.x + overRect.size.width - kTabOverlap / 2.0; |
2159 } else { | 2178 } else { |
2160 NSRect overRect = [[[tabArray_ objectAtIndex:index] view] frame]; | 2179 NSRect overRect = [[[tabArray_ objectAtIndex:index] view] frame]; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2338 for (int i = 0; i < tabStripModel_->count(); i++) { | 2357 for (int i = 0; i < tabStripModel_->count(); i++) { |
2339 [self updateIconsForContents:tabStripModel_->GetWebContentsAt(i) atIndex:i]; | 2358 [self updateIconsForContents:tabStripModel_->GetWebContentsAt(i) atIndex:i]; |
2340 } | 2359 } |
2341 } | 2360 } |
2342 | 2361 |
2343 - (void)setVisualEffectsDisabledForFullscreen:(BOOL)fullscreen { | 2362 - (void)setVisualEffectsDisabledForFullscreen:(BOOL)fullscreen { |
2344 [tabStripView_ setVisualEffectsDisabledForFullscreen:fullscreen]; | 2363 [tabStripView_ setVisualEffectsDisabledForFullscreen:fullscreen]; |
2345 } | 2364 } |
2346 | 2365 |
2347 @end | 2366 @end |
OLD | NEW |