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

Side by Side Diff: chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm

Issue 11428161: bookmarks: Break the dependency in ui/cocoa. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix2 Created 8 years 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
OLDNEW
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 #include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" 5 #include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include <cmath>
10
11 #include "base/memory/scoped_nsobject.h"
12 #include "base/sys_string_conversions.h" 9 #include "base/sys_string_conversions.h"
13 #include "chrome/browser/bookmarks/bookmark_model.h" 10 #include "chrome/browser/bookmarks/bookmark_model.h"
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
17 #include "grit/ui_resources.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/mac/nsimage_cache.h"
20 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
21 11
22 NSString* const kBookmarkDictionaryListPboardType = 12 NSString* const kBookmarkDictionaryListPboardType =
23 @"BookmarkDictionaryListPboardType"; 13 @"BookmarkDictionaryListPboardType";
24 14
25 namespace { 15 namespace {
26 16
27 // An unofficial standard pasteboard title type to be provided alongside the 17 // An unofficial standard pasteboard title type to be provided alongside the
28 // |NSURLPboardType|. 18 // |NSURLPboardType|.
29 NSString* const kNSURLTitlePboardType = 19 NSString* const kNSURLTitlePboardType =
30 @"public.url-name"; 20 @"public.url-name";
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 type_string = NSGeneralPboard; 228 type_string = NSGeneralPboard;
239 break; 229 break;
240 case bookmark_pasteboard_helper_mac::kDragPasteboard: 230 case bookmark_pasteboard_helper_mac::kDragPasteboard:
241 type_string = NSDragPboard; 231 type_string = NSDragPboard;
242 break; 232 break;
243 } 233 }
244 234
245 return [NSPasteboard pasteboardWithName:type_string]; 235 return [NSPasteboard pasteboardWithName:type_string];
246 } 236 }
247 237
248 // Make a drag image from the drop data.
249 NSImage* MakeDragImage(BookmarkModel* model,
250 const std::vector<const BookmarkNode*>& nodes) {
251 if (nodes.size() == 1) {
252 const BookmarkNode* node = nodes[0];
253 const gfx::Image& favicon = model->GetFavicon(node);
254 return bookmark_pasteboard_helper_mac::DragImageForBookmark(
255 favicon.IsEmpty() ? nil : favicon.ToNSImage(), node->GetTitle());
256 } else {
257 // TODO(feldstein): Do something better than this. Should have badging
258 // and a single drag image.
259 // http://crbug.com/37264
260 return [NSImage imageNamed:NSImageNameMultipleDocuments];
261 }
262 }
263
264 // Draws string |title| within box |frame|, positioning it at the origin.
265 // Truncates text with fading if it is too long to fit horizontally.
266 // Based on code from GradientButtonCell but simplified where possible.
267 void DrawTruncatedTitle(NSAttributedString* title, NSRect frame) {
268 NSSize size = [title size];
269 if (std::floor(size.width) <= NSWidth(frame)) {
270 [title drawAtPoint:frame.origin];
271 return;
272 }
273
274 // Gradient is about twice our line height long.
275 CGFloat gradient_width = std::min(size.height * 2, NSWidth(frame) / 4);
276 NSRect solid_part, gradient_part;
277 NSDivideRect(frame, &gradient_part, &solid_part, gradient_width, NSMaxXEdge);
278 CGContextRef context = static_cast<CGContextRef>(
279 [[NSGraphicsContext currentContext] graphicsPort]);
280 CGContextBeginTransparencyLayerWithRect(context, NSRectToCGRect(frame), 0);
281 { // Draw text clipped to frame.
282 gfx::ScopedNSGraphicsContextSaveGState scoped_state;
283 [NSBezierPath clipRect:frame];
284 [title drawAtPoint:frame.origin];
285 }
286
287 NSColor* color = [NSColor blackColor];
288 NSColor* alpha_color = [color colorWithAlphaComponent:0.0];
289 scoped_nsobject<NSGradient> mask(
290 [[NSGradient alloc] initWithStartingColor:color
291 endingColor:alpha_color]);
292 // Draw the gradient mask.
293 CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
294 [mask drawFromPoint:NSMakePoint(NSMaxX(frame) - gradient_width,
295 NSMinY(frame))
296 toPoint:NSMakePoint(NSMaxX(frame),
297 NSMinY(frame))
298 options:NSGradientDrawsBeforeStartingLocation];
299 CGContextEndTransparencyLayer(context);
300 }
301
302 } // namespace 238 } // namespace
303 239
304 namespace bookmark_pasteboard_helper_mac { 240 namespace bookmark_pasteboard_helper_mac {
305 241
306 void WriteToPasteboard(PasteboardType type, 242 void WriteToPasteboard(PasteboardType type,
307 const std::vector<BookmarkNodeData::Element>& elements, 243 const std::vector<BookmarkNodeData::Element>& elements,
308 FilePath::StringType profile_path) { 244 FilePath::StringType profile_path) {
309 if (elements.empty()) 245 if (elements.empty())
310 return; 246 return;
311 247
(...skipping 30 matching lines...) Expand all
342 NSPasteboard* pb = PasteboardFromType(type); 278 NSPasteboard* pb = PasteboardFromType(type);
343 279
344 NSArray* availableTypes = 280 NSArray* availableTypes =
345 [NSArray arrayWithObjects:kBookmarkDictionaryListPboardType, 281 [NSArray arrayWithObjects:kBookmarkDictionaryListPboardType,
346 kCrWebURLsWithTitlesPboardType, 282 kCrWebURLsWithTitlesPboardType,
347 NSURLPboardType, 283 NSURLPboardType,
348 nil]; 284 nil];
349 return [pb availableTypeFromArray:availableTypes] != nil; 285 return [pb availableTypeFromArray:availableTypes] != nil;
350 } 286 }
351 287
352 NSImage* DragImageForBookmark(NSImage* favicon, const string16& title) {
353 // If no favicon, use a default.
354 if (!favicon) {
355 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
356 favicon = rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).ToNSImage();
357 }
358
359 // If no title, just use icon.
360 if (title.empty())
361 return favicon;
362 NSString* ns_title = base::SysUTF16ToNSString(title);
363
364 // Set the look of the title.
365 NSDictionary* attrs =
366 [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:
367 [NSFont smallSystemFontSize]]
368 forKey:NSFontAttributeName];
369 scoped_nsobject<NSAttributedString> rich_title(
370 [[NSAttributedString alloc] initWithString:ns_title
371 attributes:attrs]);
372
373 // Set up sizes and locations for rendering.
374 const CGFloat kIconMargin = 2.0; // Gap between icon and text.
375 CGFloat text_left = [favicon size].width + kIconMargin;
376 NSSize drag_image_size = [favicon size];
377 NSSize text_size = [rich_title size];
378 CGFloat max_text_width = bookmarks::kDefaultBookmarkWidth - text_left;
379 text_size.width = std::min(text_size.width, max_text_width);
380 drag_image_size.width = text_left + text_size.width;
381
382 // Render the drag image.
383 NSImage* drag_image =
384 [[[NSImage alloc] initWithSize:drag_image_size] autorelease];
385 [drag_image lockFocus];
386 [favicon drawAtPoint:NSMakePoint(0, 0)
387 fromRect:NSZeroRect
388 operation:NSCompositeSourceOver
389 fraction:0.7];
390 NSRect target_text_rect = NSMakeRect(text_left, 0,
391 text_size.width, drag_image_size.height);
392 DrawTruncatedTitle(rich_title, target_text_rect);
393 [drag_image unlockFocus];
394
395 return drag_image;
396 }
397
398 void StartDrag(Profile* profile,
399 const std::vector<const BookmarkNode*>& nodes,
400 gfx::NativeView view) {
401
402 std::vector<BookmarkNodeData::Element> elements;
403 for (std::vector<const BookmarkNode*>::const_iterator it = nodes.begin();
404 it != nodes.end(); ++it) {
405 elements.push_back(BookmarkNodeData::Element(*it));
406 }
407
408 WriteToPasteboard(kDragPasteboard, elements, profile->GetPath().value());
409
410 // Synthesize an event for dragging, since we can't be sure that
411 // [NSApp currentEvent] will return a valid dragging event.
412 NSWindow* window = [view window];
413 NSPoint position = [window mouseLocationOutsideOfEventStream];
414 NSTimeInterval event_time = [[NSApp currentEvent] timestamp];
415 NSEvent* drag_event = [NSEvent mouseEventWithType:NSLeftMouseDragged
416 location:position
417 modifierFlags:NSLeftMouseDraggedMask
418 timestamp:event_time
419 windowNumber:[window windowNumber]
420 context:nil
421 eventNumber:0
422 clickCount:1
423 pressure:1.0];
424
425 // TODO(avi): Do better than this offset.
426 NSImage* drag_image =
427 MakeDragImage(BookmarkModelFactory::GetForProfile(profile), nodes);
428 NSSize image_size = [drag_image size];
429 position.x -= std::floor(image_size.width / 2);
430 position.y -= std::floor(image_size.height / 5);
431 [window dragImage:drag_image
432 at:position
433 offset:NSZeroSize
434 event:drag_event
435 pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
436 source:nil
437 slideBack:YES];
438 }
439
440 } // namespace bookmark_pasteboard_helper_mac 288 } // namespace bookmark_pasteboard_helper_mac
OLDNEW
« no previous file with comments | « chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h ('k') | chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698