Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/views/cocoa/bridged_content_view.h" | 5 #import "ui/views/cocoa/bridged_content_view.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #import "base/mac/mac_util.h" | 8 #import "base/mac/mac_util.h" |
| 9 #import "base/mac/scoped_nsobject.h" | 9 #import "base/mac/scoped_nsobject.h" |
| 10 #import "base/mac/sdk_forward_declarations.h" | 10 #import "base/mac/sdk_forward_declarations.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "ui/events/event_utils.h" | 21 #include "ui/events/event_utils.h" |
| 22 #include "ui/events/keycodes/dom/dom_code.h" | 22 #include "ui/events/keycodes/dom/dom_code.h" |
| 23 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" | 23 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" |
| 24 #include "ui/gfx/canvas_paint_mac.h" | 24 #include "ui/gfx/canvas_paint_mac.h" |
| 25 #include "ui/gfx/decorated_text.h" | 25 #include "ui/gfx/decorated_text.h" |
| 26 #include "ui/gfx/geometry/rect.h" | 26 #include "ui/gfx/geometry/rect.h" |
| 27 #import "ui/gfx/mac/coordinate_conversion.h" | 27 #import "ui/gfx/mac/coordinate_conversion.h" |
| 28 #include "ui/gfx/path.h" | 28 #include "ui/gfx/path.h" |
| 29 #import "ui/gfx/path_mac.h" | 29 #import "ui/gfx/path_mac.h" |
| 30 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 30 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| 31 #include "ui/strings/grit/ui_strings.h" | |
| 31 #import "ui/views/cocoa/bridged_native_widget.h" | 32 #import "ui/views/cocoa/bridged_native_widget.h" |
| 32 #import "ui/views/cocoa/drag_drop_client_mac.h" | 33 #import "ui/views/cocoa/drag_drop_client_mac.h" |
| 34 #include "ui/views/controls/label.h" | |
| 33 #include "ui/views/controls/menu/menu_config.h" | 35 #include "ui/views/controls/menu/menu_config.h" |
| 34 #include "ui/views/controls/menu/menu_controller.h" | 36 #include "ui/views/controls/menu/menu_controller.h" |
| 35 #include "ui/views/view.h" | 37 #include "ui/views/view.h" |
| 36 #include "ui/views/widget/native_widget_mac.h" | 38 #include "ui/views/widget/native_widget_mac.h" |
| 37 #include "ui/views/widget/widget.h" | 39 #include "ui/views/widget/widget.h" |
| 38 #include "ui/views/word_lookup_client.h" | 40 #include "ui/views/word_lookup_client.h" |
| 39 | 41 |
| 40 using views::MenuController; | 42 using views::MenuController; |
| 41 | 43 |
| 42 namespace { | 44 namespace { |
| 43 | 45 |
| 46 const int kInvalidTextMenuCommand = 0; | |
|
tapted
2016/11/16 08:39:07
0 is valid according to SimpleMenuModel::ValidateI
karandeepb
2016/11/16 23:47:13
Removed GetContextMenuCommandForMenuAction.
| |
| 47 | |
| 44 NSString* const kFullKeyboardAccessChangedNotification = | 48 NSString* const kFullKeyboardAccessChangedNotification = |
| 45 @"com.apple.KeyboardUIModeDidChange"; | 49 @"com.apple.KeyboardUIModeDidChange"; |
| 46 | 50 |
| 47 // Returns true if all four corners of |rect| are contained inside |path|. | 51 // Returns true if all four corners of |rect| are contained inside |path|. |
| 48 bool IsRectInsidePath(NSRect rect, NSBezierPath* path) { | 52 bool IsRectInsidePath(NSRect rect, NSBezierPath* path) { |
| 49 return [path containsPoint:rect.origin] && | 53 return [path containsPoint:rect.origin] && |
| 50 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, | 54 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, |
| 51 rect.origin.y)] && | 55 rect.origin.y)] && |
| 52 [path containsPoint:NSMakePoint(rect.origin.x, | 56 [path containsPoint:NSMakePoint(rect.origin.x, |
| 53 rect.origin.y + rect.size.height)] && | 57 rect.origin.y + rect.size.height)] && |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 if (attribute.strike) | 244 if (attribute.strike) |
| 241 attrs[NSStrikethroughStyleAttributeName] = line_style; | 245 attrs[NSStrikethroughStyleAttributeName] = line_style; |
| 242 | 246 |
| 243 [str setAttributes:attrs range:range]; | 247 [str setAttributes:attrs range:range]; |
| 244 } | 248 } |
| 245 | 249 |
| 246 [str endEditing]; | 250 [str endEditing]; |
| 247 return str.autorelease(); | 251 return str.autorelease(); |
| 248 } | 252 } |
| 249 | 253 |
| 254 ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { | |
| 255 if (action == @selector(undo:)) | |
| 256 return ui::TextEditCommand::UNDO; | |
| 257 if (action == @selector(redo:)) | |
| 258 return ui::TextEditCommand::REDO; | |
| 259 if (action == @selector(cut:)) | |
| 260 return ui::TextEditCommand::CUT; | |
| 261 if (action == @selector(copy:)) | |
| 262 return ui::TextEditCommand::COPY; | |
| 263 if (action == @selector(paste:)) | |
| 264 return ui::TextEditCommand::PASTE; | |
| 265 if (action == @selector(selectAll:)) | |
| 266 return ui::TextEditCommand::SELECT_ALL; | |
| 267 return ui::TextEditCommand::INVALID_COMMAND; | |
| 268 } | |
| 269 | |
| 270 int GetContextMenuCommandForMenuAction(SEL action) { | |
| 271 if (action == @selector(undo:)) | |
| 272 return IDS_APP_UNDO; | |
|
tapted
2016/11/16 08:39:07
I don't really like seeing IDS_ translated string
karandeepb
2016/11/16 23:47:13
Removed this.
| |
| 273 if (action == @selector(cut:)) | |
| 274 return IDS_APP_CUT; | |
| 275 if (action == @selector(copy:)) | |
| 276 return IDS_APP_COPY; | |
| 277 if (action == @selector(paste:)) | |
| 278 return IDS_APP_PASTE; | |
| 279 if (action == @selector(selectAll:)) | |
| 280 return IDS_APP_SELECT_ALL; | |
| 281 return kInvalidTextMenuCommand; | |
| 282 } | |
| 283 | |
| 250 } // namespace | 284 } // namespace |
| 251 | 285 |
| 252 @interface BridgedContentView () | 286 @interface BridgedContentView () |
| 253 | 287 |
| 254 // Returns the active menu controller corresponding to |hostedView_|, | 288 // Returns the active menu controller corresponding to |hostedView_|, |
| 255 // nil otherwise. | 289 // nil otherwise. |
| 256 - (MenuController*)activeMenuController; | 290 - (MenuController*)activeMenuController; |
| 257 | 291 |
| 258 // Passes |event| to the InputMethod for dispatch. | 292 // Passes |event| to the InputMethod for dispatch. |
| 259 - (void)handleKeyEvent:(ui::KeyEvent*)event; | 293 - (void)handleKeyEvent:(ui::KeyEvent*)event; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 } | 547 } |
| 514 } | 548 } |
| 515 | 549 |
| 516 - (views::DragDropClientMac*)dragDropClient { | 550 - (views::DragDropClientMac*)dragDropClient { |
| 517 views::BridgedNativeWidget* bridge = | 551 views::BridgedNativeWidget* bridge = |
| 518 views::NativeWidgetMac::GetBridgeForNativeWindow([self window]); | 552 views::NativeWidgetMac::GetBridgeForNativeWindow([self window]); |
| 519 return bridge ? bridge->drag_drop_client() : nullptr; | 553 return bridge ? bridge->drag_drop_client() : nullptr; |
| 520 } | 554 } |
| 521 | 555 |
| 522 - (void)undo:(id)sender { | 556 - (void)undo:(id)sender { |
| 523 // This DCHECK is more strict than a similar check in handleAction:. It can be | |
| 524 // done here because the actors sending these actions should be calling | |
| 525 // validateUserInterfaceItem: before enabling UI that allows these messages to | |
| 526 // be sent. Checking it here would be too late to provide correct UI feedback | |
| 527 // (e.g. there will be no "beep"). | |
| 528 DCHECK(textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::UNDO)); | |
| 529 [self handleAction:ui::TextEditCommand::UNDO | 557 [self handleAction:ui::TextEditCommand::UNDO |
| 530 keyCode:ui::VKEY_Z | 558 keyCode:ui::VKEY_Z |
| 531 domCode:ui::DomCode::US_Z | 559 domCode:ui::DomCode::US_Z |
| 532 eventFlags:ui::EF_CONTROL_DOWN]; | 560 eventFlags:ui::EF_CONTROL_DOWN]; |
| 533 } | 561 } |
| 534 | 562 |
| 535 - (void)redo:(id)sender { | 563 - (void)redo:(id)sender { |
| 536 DCHECK(textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::REDO)); | |
| 537 [self handleAction:ui::TextEditCommand::REDO | 564 [self handleAction:ui::TextEditCommand::REDO |
| 538 keyCode:ui::VKEY_Z | 565 keyCode:ui::VKEY_Z |
| 539 domCode:ui::DomCode::US_Z | 566 domCode:ui::DomCode::US_Z |
| 540 eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN]; | 567 eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN]; |
| 541 } | 568 } |
| 542 | 569 |
| 543 - (void)cut:(id)sender { | 570 - (void)cut:(id)sender { |
| 544 DCHECK(textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::CUT)); | |
| 545 [self handleAction:ui::TextEditCommand::CUT | 571 [self handleAction:ui::TextEditCommand::CUT |
| 546 keyCode:ui::VKEY_X | 572 keyCode:ui::VKEY_X |
| 547 domCode:ui::DomCode::US_X | 573 domCode:ui::DomCode::US_X |
| 548 eventFlags:ui::EF_CONTROL_DOWN]; | 574 eventFlags:ui::EF_CONTROL_DOWN]; |
| 549 } | 575 } |
| 550 | 576 |
| 551 - (void)copy:(id)sender { | 577 - (void)copy:(id)sender { |
| 552 DCHECK(textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::COPY)); | |
| 553 [self handleAction:ui::TextEditCommand::COPY | 578 [self handleAction:ui::TextEditCommand::COPY |
| 554 keyCode:ui::VKEY_C | 579 keyCode:ui::VKEY_C |
| 555 domCode:ui::DomCode::US_C | 580 domCode:ui::DomCode::US_C |
| 556 eventFlags:ui::EF_CONTROL_DOWN]; | 581 eventFlags:ui::EF_CONTROL_DOWN]; |
| 557 } | 582 } |
| 558 | 583 |
| 559 - (void)paste:(id)sender { | 584 - (void)paste:(id)sender { |
| 560 DCHECK( | |
| 561 textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::PASTE)); | |
| 562 [self handleAction:ui::TextEditCommand::PASTE | 585 [self handleAction:ui::TextEditCommand::PASTE |
| 563 keyCode:ui::VKEY_V | 586 keyCode:ui::VKEY_V |
| 564 domCode:ui::DomCode::US_V | 587 domCode:ui::DomCode::US_V |
| 565 eventFlags:ui::EF_CONTROL_DOWN]; | 588 eventFlags:ui::EF_CONTROL_DOWN]; |
| 566 } | 589 } |
| 567 | 590 |
| 568 - (void)selectAll:(id)sender { | 591 - (void)selectAll:(id)sender { |
| 569 DCHECK(textInputClient_->IsTextEditCommandEnabled( | |
| 570 ui::TextEditCommand::SELECT_ALL)); | |
| 571 [self handleAction:ui::TextEditCommand::SELECT_ALL | 592 [self handleAction:ui::TextEditCommand::SELECT_ALL |
| 572 keyCode:ui::VKEY_A | 593 keyCode:ui::VKEY_A |
| 573 domCode:ui::DomCode::US_A | 594 domCode:ui::DomCode::US_A |
| 574 eventFlags:ui::EF_CONTROL_DOWN]; | 595 eventFlags:ui::EF_CONTROL_DOWN]; |
| 575 } | 596 } |
| 576 | 597 |
| 577 // BaseView implementation. | 598 // BaseView implementation. |
| 578 | 599 |
| 579 // Don't use tracking areas from BaseView. BridgedContentView's tracks | 600 // Don't use tracking areas from BaseView. BridgedContentView's tracks |
| 580 // NSTrackingCursorUpdate and Apple's documentation suggests it's incompatible. | 601 // NSTrackingCursorUpdate and Apple's documentation suggests it's incompatible. |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1371 textInputClient_->ConfirmCompositionText(); | 1392 textInputClient_->ConfirmCompositionText(); |
| 1372 } | 1393 } |
| 1373 | 1394 |
| 1374 - (NSArray*)validAttributesForMarkedText { | 1395 - (NSArray*)validAttributesForMarkedText { |
| 1375 return @[]; | 1396 return @[]; |
| 1376 } | 1397 } |
| 1377 | 1398 |
| 1378 // NSUserInterfaceValidations protocol implementation. | 1399 // NSUserInterfaceValidations protocol implementation. |
| 1379 | 1400 |
| 1380 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { | 1401 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { |
| 1381 if (!textInputClient_) | 1402 ui::TextEditCommand command = GetTextEditCommandForMenuAction([item action]); |
| 1403 | |
| 1404 if (command == ui::TextEditCommand::INVALID_COMMAND) | |
| 1382 return NO; | 1405 return NO; |
| 1383 | 1406 |
| 1384 SEL action = [item action]; | 1407 if (textInputClient_) |
| 1408 return textInputClient_->IsTextEditCommandEnabled(command); | |
| 1385 | 1409 |
| 1386 if (action == @selector(undo:)) | 1410 // views::Label does not implement the TextInputClient interface but still |
| 1387 return textInputClient_->IsTextEditCommandEnabled( | 1411 // needs to intercept these menu actions. |
| 1388 ui::TextEditCommand::UNDO); | 1412 views::FocusManager* focus_manager = |
| 1389 if (action == @selector(redo:)) | 1413 hostedView_->GetWidget()->GetFocusManager(); |
| 1390 return textInputClient_->IsTextEditCommandEnabled( | 1414 if (!focus_manager || !focus_manager->GetFocusedView() || |
| 1391 ui::TextEditCommand::REDO); | 1415 focus_manager->GetFocusedView()->GetClassName() != |
| 1392 if (action == @selector(cut:)) | 1416 views::Label::kViewClassName) |
| 1393 return textInputClient_->IsTextEditCommandEnabled(ui::TextEditCommand::CUT); | 1417 return false; |
|
tapted
2016/11/16 08:39:07
nit: false -> NO
karandeepb
2016/11/16 23:47:13
Done.
| |
| 1394 if (action == @selector(copy:)) | |
| 1395 return textInputClient_->IsTextEditCommandEnabled( | |
| 1396 ui::TextEditCommand::COPY); | |
| 1397 if (action == @selector(paste:)) | |
| 1398 return textInputClient_->IsTextEditCommandEnabled( | |
| 1399 ui::TextEditCommand::PASTE); | |
| 1400 if (action == @selector(selectAll:)) | |
| 1401 return textInputClient_->IsTextEditCommandEnabled( | |
| 1402 ui::TextEditCommand::SELECT_ALL); | |
| 1403 | 1418 |
| 1404 return NO; | 1419 views::Label* label = |
|
tapted
2016/11/16 08:39:07
I think this could safely just `return YES`. Right
karandeepb
2016/11/16 23:47:13
Not really, left clicking a label will give focus
| |
| 1420 static_cast<views::Label*>(focus_manager->GetFocusedView()); | |
| 1421 return static_cast<ui::SimpleMenuModel::Delegate*>(label)->IsCommandIdEnabled( | |
|
tapted
2016/11/16 08:39:07
you could get rid of this static_cast by assigning
karandeepb
2016/11/16 23:47:13
Yeah I remember seeing a thread about this earlier
| |
| 1422 GetContextMenuCommandForMenuAction([item action])); | |
| 1405 } | 1423 } |
| 1406 | 1424 |
| 1407 // NSDraggingSource protocol implementation. | 1425 // NSDraggingSource protocol implementation. |
| 1408 | 1426 |
| 1409 - (NSDragOperation)draggingSession:(NSDraggingSession*)session | 1427 - (NSDragOperation)draggingSession:(NSDraggingSession*)session |
| 1410 sourceOperationMaskForDraggingContext:(NSDraggingContext)context { | 1428 sourceOperationMaskForDraggingContext:(NSDraggingContext)context { |
| 1411 return NSDragOperationEvery; | 1429 return NSDragOperationEvery; |
| 1412 } | 1430 } |
| 1413 | 1431 |
| 1414 - (void)draggingSession:(NSDraggingSession*)session | 1432 - (void)draggingSession:(NSDraggingSession*)session |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1433 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; | 1451 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; |
| 1434 } | 1452 } |
| 1435 | 1453 |
| 1436 - (id)accessibilityFocusedUIElement { | 1454 - (id)accessibilityFocusedUIElement { |
| 1437 if (!hostedView_) | 1455 if (!hostedView_) |
| 1438 return nil; | 1456 return nil; |
| 1439 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement]; | 1457 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement]; |
| 1440 } | 1458 } |
| 1441 | 1459 |
| 1442 @end | 1460 @end |
| OLD | NEW |