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

Unified Diff: chrome/browser/autocomplete/autocomplete_edit_view_mac.mm

Issue 113479: Mac: Style the omnibox URL. (Closed)
Patch Set: Fix a couple comments, and saving across popup navigation. Created 11 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
index dc1a6f5eac8c87bc9e7c6ccc497db3fea8665391..0a22805b31cb63121c3eef57a962ea11686ea27b 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
@@ -12,6 +12,41 @@
namespace {
+// TODO(shess): This is ugly, find a better way. Using it right now
+// so that I can crib from gtk and still be able to see that I'm using
+// the same values easily.
+const NSColor* ColorWithRGBBytes(int rr, int gg, int bb) {
+ DCHECK_LE(rr, 255);
+ DCHECK_LE(bb, 255);
+ DCHECK_LE(gg, 255);
+ return [NSColor colorWithCalibratedRed:static_cast<float>(rr)/255.0
+ green:static_cast<float>(gg)/255.0
+ blue:static_cast<float>(bb)/255.0
+ alpha:1.0];
+}
+const NSColor* SecureBackgroundColor() {
+ return ColorWithRGBBytes(255, 245, 195); // Yellow
+}
+const NSColor* NormalBackgroundColor() {
+ return [NSColor controlBackgroundColor];
+}
+const NSColor* InsecureBackgroundColor() {
+ return [NSColor controlBackgroundColor];
+}
+
+const NSColor* HostTextColor() {
+ return [NSColor blackColor];
+}
+const NSColor* BaseTextColor() {
+ return [NSColor darkGrayColor];
+}
+const NSColor* SecureSchemeColor() {
+ return ColorWithRGBBytes(0x00, 0x96, 0x14);
+}
+const NSColor* InsecureSchemeColor() {
+ return ColorWithRGBBytes(0xc8, 0x00, 0x00);
+}
+
// Store's the model and view state across tab switches.
struct AutocompleteEditViewMacState {
AutocompleteEditViewMacState(const AutocompleteEditModel::State model_state,
@@ -44,6 +79,13 @@ const AutocompleteEditViewMacState* GetStateFromTab(const TabContents* tab) {
return GetStateAccessor()->GetProperty(tab->property_bag());
}
+// Helper to make converting url_parse ranges to NSRange easier to
+// read.
+NSRange ComponentToNSRange(const url_parse::Component& component) {
+ return NSMakeRange(static_cast<NSInteger>(component.begin),
+ static_cast<NSInteger>(component.len));
+}
+
} // namespace
// Thin Obj-C bridge class that is the delegate of the omnibox field.
@@ -77,6 +119,9 @@ AutocompleteEditViewMac::AutocompleteEditViewMac(
DCHECK(command_updater);
DCHECK(field);
[field_ setDelegate:edit_helper_];
+
+ // Needed so that editing doesn't lose the styling.
+ [field_ setAllowsEditingTextAttributes:YES];
}
AutocompleteEditViewMac::~AutocompleteEditViewMac() {
@@ -137,9 +182,7 @@ void AutocompleteEditViewMac::Update(
// not restoring focus is an oversight, or intentional for some
// subtle reason.
if (state->has_focus) {
- FocusLocation();
- DCHECK([field_ currentEditor]);
- [[field_ currentEditor] setSelectedRange:state->selection];
+ SetSelectedRange(state->selection);
}
}
} else if (user_visible) {
@@ -151,10 +194,7 @@ void AutocompleteEditViewMac::Update(
} else {
// TODO(shess): Figure out how this case is used, to make sure
// we're getting the selection and popup right.
- // UpdateAndStyleText() approximates the inner part of Revertall()
- // which under GTK is called EmphasizeURLComponents(), and is
- // expected to change when I start feeding in the styling code.
- UpdateAndStyleText(text, 0);
+ UpdateAndStyleText(text);
}
}
@@ -187,7 +227,9 @@ void AutocompleteEditViewMac::SetUserText(const std::wstring& text,
const std::wstring& display_text,
bool update_popup) {
model_->SetUserText(text);
- UpdateAndStyleText(display_text, display_text.size());
+ // TODO(shess): TODO below from gtk.
+ // TODO(deanm): something about selection / focus change here.
+ UpdateAndStyleText(display_text);
if (update_popup) {
UpdatePopup();
}
@@ -198,24 +240,40 @@ NSRange AutocompleteEditViewMac::GetSelectedRange() const {
return [[field_ currentEditor] selectedRange];
}
+void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) {
+ // TODO(shess): Check if we should steal focus or not. We can't set
+ // the selection without focus, though.
+ FocusLocation();
+
+ // TODO(shess): What if it didn't get first responder, and there is
+ // no field editor? This will do nothing. Well, at least it won't
+ // crash. Think of something more productive to do, or prove that
+ // it cannot occur and DCHECK appropriately.
+ [[field_ currentEditor] setSelectedRange:range];
+}
+
void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text,
size_t caret_pos) {
- UpdateAndStyleText(text, text.size());
+ DCHECK_LE(caret_pos, text.size());
+ UpdateAndStyleText(text);
+ SetSelectedRange(NSMakeRange(caret_pos, caret_pos));
}
void AutocompleteEditViewMac::SelectAll(bool reversed) {
- // TODO(shess): Figure out what reversed implies. The gtk version
+ // TODO(shess): Figure out what |reversed| implies. The gtk version
// has it imply inverting the selection front to back, but I don't
// even know if that makes sense for Mac.
- UpdateAndStyleText(GetText(), 0);
+
+ // TODO(shess): Verify that we should be stealing focus at this
+ // point.
+ SetSelectedRange(NSMakeRange(0, GetText().size()));
}
void AutocompleteEditViewMac::RevertAll() {
ClosePopup();
model_->Revert();
- std::wstring tt = GetText();
- UpdateAndStyleText(tt, 0);
+ UpdateAndStyleText(GetText());
controller_->OnChanged();
}
@@ -238,61 +296,56 @@ void AutocompleteEditViewMac::ClosePopup() {
}
void AutocompleteEditViewMac::UpdateAndStyleText(
- const std::wstring& display_text, size_t user_text_length) {
- NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
- [field_ font], NSFontAttributeName,
- nil];
+ const std::wstring& display_text) {
NSString* ss = base::SysWideToNSString(display_text);
NSMutableAttributedString* as =
- [[[NSMutableAttributedString alloc] initWithString:ss
- attributes:attributes]
- autorelease];
+ [[[NSMutableAttributedString alloc] initWithString:ss] autorelease];
+ [as addAttribute:NSFontAttributeName value:[field_ font]
+ range:NSMakeRange(0, [as length])];
url_parse::Parsed parts;
AutocompleteInput::Parse(display_text, model_->GetDesiredTLD(),
&parts, NULL);
- bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0);
+ const bool emphasize = model_->CurrentTextIsURL() && (parts.host.len > 0);
if (emphasize) {
- // TODO(shess): Pull color out as a constant.
- [as addAttribute:NSForegroundColorAttributeName
- value:[NSColor greenColor]
- range:NSMakeRange((NSInteger)parts.host.begin,
- (NSInteger)parts.host.len)];
+ [as addAttribute:NSForegroundColorAttributeName value:BaseTextColor()
+ range:NSMakeRange(0, [as length])];
+
+ [as addAttribute:NSForegroundColorAttributeName value:HostTextColor()
+ range:ComponentToNSRange(parts.host)];
}
// TODO(shess): GTK has this as a member var, figure out why.
- ToolbarModel::SecurityLevel scheme_security_level =
+ // [Could it be to not change if no change? If so, I'm guessing
+ // AppKit may already handle that.]
+ const ToolbarModel::SecurityLevel scheme_security_level =
toolbar_model_->GetSchemeSecurityLevel();
+ if (scheme_security_level == ToolbarModel::SECURE) {
+ [field_ setBackgroundColor:SecureBackgroundColor()];
+ } else if (scheme_security_level == ToolbarModel::NORMAL) {
+ [field_ setBackgroundColor:NormalBackgroundColor()];
+ } else if (scheme_security_level == ToolbarModel::INSECURE) {
+ [field_ setBackgroundColor:InsecureBackgroundColor()];
+ } else {
+ NOTREACHED() << "Unexpected scheme_security_level: "
+ << scheme_security_level;
+ }
+
// Emphasize the scheme for security UI display purposes (if necessary).
if (!model_->user_input_in_progress() && parts.scheme.is_nonempty() &&
(scheme_security_level != ToolbarModel::NORMAL)) {
- // TODO(shess): Pull colors out as constants.
NSColor* color;
if (scheme_security_level == ToolbarModel::SECURE) {
- color = [NSColor blueColor];
+ color = SecureSchemeColor();
} else {
- color = [NSColor blackColor];
+ color = InsecureSchemeColor();
}
[as addAttribute:NSForegroundColorAttributeName value:color
- range:NSMakeRange((NSInteger)parts.scheme.begin,
- (NSInteger)parts.scheme.len)];
+ range:ComponentToNSRange(parts.scheme)];
}
- // TODO(shess): Check that this updates the model's sense of focus
- // correctly.
[field_ setObjectValue:as];
- if (![field_ currentEditor]) {
- [field_ becomeFirstResponder];
- DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]);
- }
-
- NSRange selected_range = NSMakeRange(user_text_length, [as length]);
- // TODO(shess): What if it didn't get first responder, and there is
- // no field editor? This will do nothing. Well, at least it won't
- // crash. Think of something more productive to do, or prove that
- // it cannot occur and DCHECK appropriately.
- [[field_ currentEditor] setSelectedRange:selected_range];
}
void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged(
@@ -301,10 +354,11 @@ void AutocompleteEditViewMac::OnTemporaryTextMaybeChanged(
// the popup, will be restored if they hit escape. Figure out if
// that is for certain it.
if (save_original_selection) {
+ saved_temporary_selection_ = GetSelectedRange();
saved_temporary_text_ = GetText();
}
- UpdateAndStyleText(display_text, display_text.size());
+ SetWindowTextAndCaretPos(display_text, display_text.size());
}
bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged(
@@ -316,13 +370,16 @@ bool AutocompleteEditViewMac::OnInlineAutocompleteTextMaybeChanged(
return false;
}
- UpdateAndStyleText(display_text, user_text_length);
+ UpdateAndStyleText(display_text);
+ DCHECK_LE(user_text_length, display_text.size());
+ SetSelectedRange(NSMakeRange(user_text_length, display_text.size()));
return true;
}
void AutocompleteEditViewMac::OnRevertTemporaryText() {
- UpdateAndStyleText(saved_temporary_text_, saved_temporary_text_.size());
+ UpdateAndStyleText(saved_temporary_text_);
saved_temporary_text_.clear();
+ SetSelectedRange(saved_temporary_selection_);
}
void AutocompleteEditViewMac::OnBeforePossibleChange() {
@@ -331,14 +388,14 @@ void AutocompleteEditViewMac::OnBeforePossibleChange() {
}
bool AutocompleteEditViewMac::OnAfterPossibleChange() {
- NSRange new_selection(GetSelectedRange());
- std::wstring new_text(GetText());
+ const NSRange new_selection(GetSelectedRange());
+ const std::wstring new_text(GetText());
const size_t length = new_text.length();
- bool selection_differs = !NSEqualRanges(new_selection,
- selection_before_change_);
- bool at_end_of_edit = (length == new_selection.location);
- bool text_differs = (new_text != text_before_change_);
+ const bool selection_differs = !NSEqualRanges(new_selection,
+ selection_before_change_);
+ const bool at_end_of_edit = (length == new_selection.location);
+ const bool text_differs = (new_text != text_before_change_);
// When the user has deleted text, we don't allow inline
// autocomplete. This is assumed if the text has gotten shorter AND
@@ -350,21 +407,33 @@ bool AutocompleteEditViewMac::OnAfterPossibleChange() {
// and other methods to provide positive knowledge that a delete
// occured, rather than intuiting it from context. Consider whether
// that would be a stronger approach.
- bool just_deleted_text =
+ const bool just_deleted_text =
(length < text_before_change_.length() &&
new_selection.location <= selection_before_change_.location);
- bool something_changed = model_->OnAfterPossibleChange(new_text,
+ const bool something_changed = model_->OnAfterPossibleChange(new_text,
selection_differs, text_differs, just_deleted_text, at_end_of_edit);
- // TODO(shess): Restyle the text if something_changed. Not fixing
- // now because styling is currently broken.
+ // Restyle if the user changed something.
+ // TODO(shess): Does this need to diver deeper to avoid flashing?
+ // For instance, if the user types "/" after the hostname, will it
+ // show as HostTextColor() for an instant before being replaced by
+ // BaseTextColor(). This could probably be done by subclassing the
+ // cell and intercepting draw requests so that we draw the right
+ // thing every time.
+ // NOTE(shess): That kind of thing would also help with when the
+ // flashing from when the user's typing replaces the selection which
+ // is then re-created with the new autocomplete results.
+ if (something_changed) {
+ UpdateAndStyleText(new_text);
+ SetSelectedRange(new_selection);
+ }
return something_changed;
}
void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) {
- int count = by_page ? model_->result().size() : 1;
+ const int count = by_page ? model_->result().size() : 1;
model_->OnUpOrDownKeyPressed(up ? -count : count);
}
void AutocompleteEditViewMac::OnEscapeKeyPressed() {
@@ -387,6 +456,7 @@ void AutocompleteEditViewMac::FocusLocation() {
// current selection.
if (![field_ currentEditor]) {
[[field_ window] makeFirstResponder:field_];
+ DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]);
}
}
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698