summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete
diff options
context:
space:
mode:
authordeanm@chromium.org <deanm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 15:34:07 +0000
committerdeanm@chromium.org <deanm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 15:34:07 +0000
commitaf3007ee6faba103422849943886fe86aac52939 (patch)
tree53375960d7cc8fa115bf3912204f986565d27207 /chrome/browser/autocomplete
parentf387f1b80dc74fd2d77820e23b885e7984455763 (diff)
downloadchromium_src-af3007ee6faba103422849943886fe86aac52939.zip
chromium_src-af3007ee6faba103422849943886fe86aac52939.tar.gz
chromium_src-af3007ee6faba103422849943886fe86aac52939.tar.bz2
Make AutocompletePopupView a virtual interface.
The AutocompletePopupModel needs to be able to communicate with the view. Since the view implementation will be platform specific, we abstract our a virtual interface that the different platform view implementations must all implement. This allows the Model and View to communicate, while hiding the platform differences. This change makes the previous Windows AutocompletePopupView into AutocompletePopupViewWin, a subclass of AutocompletePopupView. Review URL: http://codereview.chromium.org/28258 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10607 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_model.cc4
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view.h197
-rwxr-xr-xchrome/browser/autocomplete/autocomplete_popup_view_win.cc455
3 files changed, 346 insertions, 310 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.cc b/chrome/browser/autocomplete/autocomplete_popup_model.cc
index 1e2f21f..1d41c14 100644
--- a/chrome/browser/autocomplete/autocomplete_popup_model.cc
+++ b/chrome/browser/autocomplete/autocomplete_popup_model.cc
@@ -29,7 +29,7 @@ AutocompletePopupModel::AutocompletePopupModel(
AutocompleteEditView* edit_view,
AutocompleteEditModel* edit_model,
Profile* profile)
- : view_(new AutocompletePopupView(this, font, edit_view)),
+ : view_(AutocompletePopupView::CreatePopupView(this, font, edit_view)),
edit_model_(edit_model),
controller_(new AutocompleteController(profile)),
profile_(profile),
@@ -143,7 +143,7 @@ void AutocompletePopupModel::SetSelectedLine(size_t line,
view_->InvalidateLine(selected_line_);
selected_line_ = line;
view_->InvalidateLine(selected_line_);
- view_->UpdateWindow();
+ view_->PaintUpdatesNow();
}
void AutocompletePopupModel::ResetToDefaultMatch() {
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view.h b/chrome/browser/autocomplete/autocomplete_popup_view.h
index 235e342..0db0af6 100644
--- a/chrome/browser/autocomplete/autocomplete_popup_view.h
+++ b/chrome/browser/autocomplete/autocomplete_popup_view.h
@@ -2,200 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file defines the interface class AutocompletePopupView. Each toolkit
+// will implement the popup view differently, so that code is inheriently
+// platform specific. However, the AutocompletePopupModel needs to do some
+// communication with the view. Since the model is shared between platforms,
+// we need to define an interface that all view implementations will share.
+
#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_H_
#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_H_
-#include <atlbase.h>
-#include <atlapp.h>
-#include <atlcrack.h>
-#include <atlmisc.h>
-
-#include "base/win_util.h"
-#include "chrome/browser/autocomplete/autocomplete.h"
-#include "chrome/common/gfx/chrome_font.h"
-#include "chrome/views/view.h"
+#include "base/basictypes.h"
class AutocompleteEditView;
-class MirroringContext;
-class SkBitmap;
-
class AutocompletePopupModel;
+class ChromeFont;
-// TODO(pkasting): http://b/1343512 The names and contents of the classes in
-// this file are temporary. I am in hack-and-slash mode right now.
-
-#define AUTOCOMPLETEPOPUPVIEW_CLASSNAME L"Chrome_AutocompletePopupView"
-
-// This class implements a popup window used to display autocomplete results.
-class AutocompletePopupView
- : public CWindowImpl<AutocompletePopupView, CWindow, CControlWinTraits> {
+class AutocompletePopupView {
public:
- DECLARE_WND_CLASS_EX(AUTOCOMPLETEPOPUPVIEW_CLASSNAME,
- ((win_util::GetWinVersion() < win_util::WINVERSION_XP) ?
- 0 : CS_DROPSHADOW), COLOR_WINDOW)
-
- BEGIN_MSG_MAP(AutocompletePopupView)
- MSG_WM_ERASEBKGND(OnEraseBkgnd)
- MSG_WM_LBUTTONDOWN(OnLButtonDown)
- MSG_WM_MBUTTONDOWN(OnMButtonDown)
- MSG_WM_LBUTTONUP(OnLButtonUp)
- MSG_WM_MBUTTONUP(OnMButtonUp)
- MSG_WM_MOUSEACTIVATE(OnMouseActivate)
- MSG_WM_MOUSELEAVE(OnMouseLeave)
- MSG_WM_MOUSEMOVE(OnMouseMove)
- MSG_WM_PAINT(OnPaint)
- END_MSG_MAP()
+ static AutocompletePopupView* CreatePopupView(
+ AutocompletePopupModel* model,
+ const ChromeFont& font,
+ AutocompleteEditView* edit_view);
- AutocompletePopupView(AutocompletePopupModel* model,
- const ChromeFont& font,
- AutocompleteEditView* edit_view);
+ virtual ~AutocompletePopupView() { }
// Returns true if the popup is currently open.
- bool IsOpen() const { return m_hWnd != NULL; }
+ virtual bool IsOpen() const = 0;
// Invalidates one line of the autocomplete popup.
- void InvalidateLine(size_t line);
+ virtual void InvalidateLine(size_t line) = 0;
// Redraws the popup window to match any changes in the result set; this may
// mean opening or closing the window.
- void UpdatePopupAppearance();
+ virtual void UpdatePopupAppearance() = 0;
// Called by the model when hover is enabled or disabled.
- void OnHoverEnabledOrDisabled(bool disabled);
-
- private:
- // Caches GDI objects and information for drawing.
- struct DrawLineInfo {
- enum LineStatus {
- NORMAL = 0,
- HOVERED,
- SELECTED,
- MAX_STATUS_ENTRIES
- };
-
- explicit DrawLineInfo(const ChromeFont& font);
- ~DrawLineInfo();
-
- static COLORREF AlphaBlend(COLORREF foreground,
- COLORREF background,
- BYTE alpha);
-
- static const wchar_t ellipsis_str[];
-
- ChromeFont regular_font; // Fonts used for rendering AutocompleteMatches.
- ChromeFont bold_font;
- int font_height; // Height (in pixels) of a line of text w/o
- // padding.
- int line_height; // Height (in pixels) of a line of text w/padding.
- int ave_char_width; // Width (in pixels) of an average character of
- // the regular font.
- int ellipsis_width; // Width (in pixels) of the ellipsis_str.
-
- // colors
- COLORREF background_colors[MAX_STATUS_ENTRIES];
- COLORREF text_colors[MAX_STATUS_ENTRIES];
- COLORREF url_colors[MAX_STATUS_ENTRIES];
-
- // brushes
- HBRUSH brushes[MAX_STATUS_ENTRIES];
-
- private:
- static double LuminosityContrast(COLORREF color1, COLORREF color2);
- static double Luminosity(COLORREF color);
- };
-
- // message handlers
- LRESULT OnEraseBkgnd(HDC hdc) {
- // We do all needed erasing ourselves in OnPaint, so the only thing that
- // WM_ERASEBKGND will do is cause flicker. Disable it by just returning
- // nonzero here ("erase completed") without doing anything.
- return 1;
- }
- void OnLButtonDown(UINT keys, const CPoint& point);
- void OnMButtonDown(UINT keys, const CPoint& point);
- void OnLButtonUp(UINT keys, const CPoint& point);
- void OnMButtonUp(UINT keys, const CPoint& point);
- LRESULT OnMouseActivate(HWND window, UINT hit_test, UINT mouse_message);
- void OnMouseLeave();
- void OnMouseMove(UINT keys, const CPoint& point);
- void OnPaint(HDC hdc);
-
- // Called by On*ButtonUp() to do the actual work of handling a button
- // release. Opens the item at the given coordinate, using the supplied
- // disposition.
- void OnButtonUp(const CPoint& point, WindowOpenDisposition disposition);
-
- // Gives the topmost y coordinate within |line|, which should be within the
- // range of valid lines.
- int LineTopPixel(size_t line) const;
-
- // Converts the given y-coordinate to a line. Due to drawing slop (window
- // borders, etc.), |y| might be within the window but outside the range of
- // pixels which correspond to lines; in this case the result will be clamped,
- // i.e., the top and bottom lines will be treated as extending to the top and
- // bottom edges of the window, respectively.
- size_t PixelToLine(int y) const;
-
- // Draws a light border around the inside of the window with the given client
- // rectangle and DC.
- void DrawBorder(const RECT& rc, HDC dc);
-
- // Draws a single run of text with a particular style. Handles both LTR and
- // RTL text as well as eliding. Returns the width, in pixels, of the string
- // as it was actually displayed.
- int DrawString(HDC dc,
- int x,
- int y,
- int max_x,
- const wchar_t* text,
- int length,
- int style,
- const DrawLineInfo::LineStatus status,
- const MirroringContext* context,
- bool text_direction_is_rtl) const;
-
- // Draws a string from the autocomplete controller which can have specially
- // marked "match" portions.
- void DrawMatchFragments(HDC dc,
- const std::wstring& text,
- const ACMatchClassifications& classifications,
- int x,
- int y,
- int max_x,
- DrawLineInfo::LineStatus status) const;
-
- // Draws one line of the text in the box.
- void DrawEntry(HDC dc,
- const RECT& client_rect,
- size_t line,
- DrawLineInfo::LineStatus status,
- bool all_descriptions_empty,
- bool starred) const;
-
- // Draws the star at the specified location
- void DrawStar(HDC dc, int x, int y) const;
-
- AutocompletePopupModel* model_;
-
- AutocompleteEditView* edit_view_;
-
- // Cached GDI information for drawing.
- DrawLineInfo line_info_;
-
- // Bitmap for the star. This is owned by the ResourceBundle.
- SkBitmap* star_;
-
- // A context used for mirroring regions.
- scoped_ptr<MirroringContext> mirroring_context_;
-
- // When hovered_line_ is kNoMatch, this holds the screen coordinates of the
- // mouse position when hover tracking was turned off. If the mouse moves to a
- // point over the popup that has different coordinates, hover tracking will be
- // re-enabled. When hovered_line_ is a valid line, the value here is
- // out-of-date and should be ignored.
- CPoint last_hover_coordinates_;
+ virtual void OnHoverEnabledOrDisabled(bool disabled) = 0;
- DISALLOW_COPY_AND_ASSIGN(AutocompletePopupView);
+#if defined(OS_WIN)
+ // Cause a WM_PAINT immediately (see msdn on UpdateWindow()).
+ virtual void PaintUpdatesNow() = 0;
+#endif
};
#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_H_
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_win.cc b/chrome/browser/autocomplete/autocomplete_popup_view_win.cc
index dd122ee..c357fa7 100755
--- a/chrome/browser/autocomplete/autocomplete_popup_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_popup_view_win.cc
@@ -37,8 +37,6 @@ namespace {
// Padding between text and the star indicator, in pixels.
const int kStarPadding = 4;
-} // namespace
-
// This class implements a utility used for mirroring x-coordinates when the
// application language is a right-to-left one.
class MirroringContext {
@@ -84,11 +82,287 @@ int MirroringContext::GetLeft(int x1, int x2) const {
(center_x_ + (center_x_ - std::max(x1, x2))) : std::min(x1, x2);
}
-const wchar_t AutocompletePopupView::DrawLineInfo::ellipsis_str[] = L"\x2026";
+// Caches GDI objects and information for drawing.
+struct DrawLineInfo {
+ enum LineStatus {
+ NORMAL = 0,
+ HOVERED,
+ SELECTED,
+ MAX_STATUS_ENTRIES
+ };
+
+ explicit DrawLineInfo(const ChromeFont& font);
+ ~DrawLineInfo();
+
+ static COLORREF AlphaBlend(COLORREF foreground,
+ COLORREF background,
+ BYTE alpha);
+
+ static const wchar_t ellipsis_str[];
+
+ ChromeFont regular_font; // Fonts used for rendering AutocompleteMatches.
+ ChromeFont bold_font;
+ int font_height; // Height (in pixels) of a line of text w/o
+ // padding.
+ int line_height; // Height (in pixels) of a line of text w/padding.
+ int ave_char_width; // Width (in pixels) of an average character of
+ // the regular font.
+ int ellipsis_width; // Width (in pixels) of the ellipsis_str.
+
+ // colors
+ COLORREF background_colors[MAX_STATUS_ENTRIES];
+ COLORREF text_colors[MAX_STATUS_ENTRIES];
+ COLORREF url_colors[MAX_STATUS_ENTRIES];
+
+ // brushes
+ HBRUSH brushes[MAX_STATUS_ENTRIES];
+
+ private:
+ static double LuminosityContrast(COLORREF color1, COLORREF color2);
+ static double Luminosity(COLORREF color);
+};
+
+const wchar_t DrawLineInfo::ellipsis_str[] = L"\x2026";
+
+DrawLineInfo::DrawLineInfo(const ChromeFont& font) {
+ // Create regular and bold fonts.
+ regular_font = font.DeriveFont(-1);
+ bold_font = regular_font.DeriveFont(0, ChromeFont::BOLD);
+
+ // The total padding added to each line (bottom padding is what is
+ // left over after DrawEntry() specifies its top offset).
+ static const int kTotalLinePadding = 5;
+ font_height = std::max(regular_font.height(), bold_font.height());
+ line_height = font_height + kTotalLinePadding;
+ ave_char_width = regular_font.GetExpectedTextWidth(1);
+ ellipsis_width = std::max(regular_font.GetStringWidth(ellipsis_str),
+ bold_font.GetStringWidth(ellipsis_str));
+
+ // Create background colors.
+ background_colors[NORMAL] = GetSysColor(COLOR_WINDOW);
+ background_colors[SELECTED] = GetSysColor(COLOR_HIGHLIGHT);
+ background_colors[HOVERED] =
+ AlphaBlend(background_colors[SELECTED], background_colors[NORMAL], 0x40);
+
+ // Create text colors.
+ text_colors[NORMAL] = GetSysColor(COLOR_WINDOWTEXT);
+ text_colors[HOVERED] = text_colors[NORMAL];
+ text_colors[SELECTED] = GetSysColor(COLOR_HIGHLIGHTTEXT);
+
+ // Create brushes and url colors.
+ const COLORREF dark_url(0x008000);
+ const COLORREF light_url(0xd0ffd0);
+ for (int i = 0; i < MAX_STATUS_ENTRIES; ++i) {
+ // Pick whichever URL color contrasts better.
+ const double dark_contrast =
+ LuminosityContrast(dark_url, background_colors[i]);
+ const double light_contrast =
+ LuminosityContrast(light_url, background_colors[i]);
+ url_colors[i] = (dark_contrast > light_contrast) ? dark_url : light_url;
+
+ brushes[i] = CreateSolidBrush(background_colors[i]);
+ }
+}
+
+DrawLineInfo::~DrawLineInfo() {
+ for (int i = 0; i < MAX_STATUS_ENTRIES; ++i)
+ DeleteObject(brushes[i]);
+}
+
+// static
+double DrawLineInfo::LuminosityContrast(
+ COLORREF color1,
+ COLORREF color2) {
+ // This algorithm was adapted from the following text at
+ // http://juicystudio.com/article/luminositycontrastratioalgorithm.php :
+ //
+ // "[Luminosity contrast can be calculated as] (L1+.05) / (L2+.05) where L is
+ // luminosity and is defined as .2126*R + .7152*G + .0722B using linearised
+ // R, G, and B values. Linearised R (for example) = (R/FS)^2.2 where FS is
+ // full scale value (255 for 8 bit color channels). L1 is the higher value
+ // (of text or background) and L2 is the lower value.
+ //
+ // The Gamma correction and RGB constants are derived from the Standard
+ // Default Color Space for the Internet (sRGB), and the 0.05 offset is
+ // included to compensate for contrast ratios that occur when a value is at
+ // or near zero, and for ambient light effects.
+ const double l1 = Luminosity(color1);
+ const double l2 = Luminosity(color2);
+ return (l1 > l2) ? ((l1 + 0.05) / (l2 + 0.05)) : ((l2 + 0.05) / (l1 + 0.05));
+}
+
+// static
+double DrawLineInfo::Luminosity(COLORREF color) {
+ // See comments in LuminosityContrast().
+ const double linearised_r =
+ pow(static_cast<double>(GetRValue(color)) / 255.0, 2.2);
+ const double linearised_g =
+ pow(static_cast<double>(GetGValue(color)) / 255.0, 2.2);
+ const double linearised_b =
+ pow(static_cast<double>(GetBValue(color)) / 255.0, 2.2);
+ return (0.2126 * linearised_r) + (0.7152 * linearised_g) +
+ (0.0722 * linearised_b);
+}
+
+COLORREF DrawLineInfo::AlphaBlend(COLORREF foreground,
+ COLORREF background,
+ BYTE alpha) {
+ if (alpha == 0)
+ return background;
+ else if (alpha == 0xff)
+ return foreground;
+
+ return RGB(
+ ((GetRValue(foreground) * alpha) +
+ (GetRValue(background) * (0xff - alpha))) / 0xff,
+ ((GetGValue(foreground) * alpha) +
+ (GetGValue(background) * (0xff - alpha))) / 0xff,
+ ((GetBValue(foreground) * alpha) +
+ (GetBValue(background) * (0xff - alpha))) / 0xff);
+}
+
+#define AUTOCOMPLETEPOPUPVIEW_CLASSNAME L"Chrome_AutocompletePopupView"
+
+// This class implements a popup window used to display autocomplete results.
+class AutocompletePopupViewWin
+ : public CWindowImpl<AutocompletePopupViewWin, CWindow, CControlWinTraits>,
+ public AutocompletePopupView {
+ public:
+ DECLARE_WND_CLASS_EX(AUTOCOMPLETEPOPUPVIEW_CLASSNAME,
+ ((win_util::GetWinVersion() < win_util::WINVERSION_XP) ?
+ 0 : CS_DROPSHADOW), COLOR_WINDOW)
+
+ BEGIN_MSG_MAP(AutocompletePopupViewWin)
+ MSG_WM_ERASEBKGND(OnEraseBkgnd)
+ MSG_WM_LBUTTONDOWN(OnLButtonDown)
+ MSG_WM_MBUTTONDOWN(OnMButtonDown)
+ MSG_WM_LBUTTONUP(OnLButtonUp)
+ MSG_WM_MBUTTONUP(OnMButtonUp)
+ MSG_WM_MOUSEACTIVATE(OnMouseActivate)
+ MSG_WM_MOUSELEAVE(OnMouseLeave)
+ MSG_WM_MOUSEMOVE(OnMouseMove)
+ MSG_WM_PAINT(OnPaint)
+ END_MSG_MAP()
+
+ AutocompletePopupViewWin(AutocompletePopupModel* model,
+ const ChromeFont& font,
+ AutocompleteEditView* edit_view);
+
+ // Returns true if the popup is currently open.
+ virtual bool IsOpen() const { return m_hWnd != NULL; }
+
+ // Invalidates one line of the autocomplete popup.
+ virtual void InvalidateLine(size_t line);
+
+ // Redraws the popup window to match any changes in the result set; this may
+ // mean opening or closing the window.
+ virtual void UpdatePopupAppearance();
+
+ // Called by the model when hover is enabled or disabled.
+ virtual void OnHoverEnabledOrDisabled(bool disabled);
+
+ virtual void PaintUpdatesNow() { UpdateWindow(); }
-AutocompletePopupView::AutocompletePopupView(AutocompletePopupModel* model,
- const ChromeFont& font,
- AutocompleteEditView* edit_view)
+ private:
+
+ // message handlers
+ LRESULT OnEraseBkgnd(HDC hdc) {
+ // We do all needed erasing ourselves in OnPaint, so the only thing that
+ // WM_ERASEBKGND will do is cause flicker. Disable it by just returning
+ // nonzero here ("erase completed") without doing anything.
+ return 1;
+ }
+ void OnLButtonDown(UINT keys, const CPoint& point);
+ void OnMButtonDown(UINT keys, const CPoint& point);
+ void OnLButtonUp(UINT keys, const CPoint& point);
+ void OnMButtonUp(UINT keys, const CPoint& point);
+ LRESULT OnMouseActivate(HWND window, UINT hit_test, UINT mouse_message);
+ void OnMouseLeave();
+ void OnMouseMove(UINT keys, const CPoint& point);
+ void OnPaint(HDC hdc);
+
+ // Called by On*ButtonUp() to do the actual work of handling a button
+ // release. Opens the item at the given coordinate, using the supplied
+ // disposition.
+ void OnButtonUp(const CPoint& point, WindowOpenDisposition disposition);
+
+ // Gives the topmost y coordinate within |line|, which should be within the
+ // range of valid lines.
+ int LineTopPixel(size_t line) const;
+
+ // Converts the given y-coordinate to a line. Due to drawing slop (window
+ // borders, etc.), |y| might be within the window but outside the range of
+ // pixels which correspond to lines; in this case the result will be clamped,
+ // i.e., the top and bottom lines will be treated as extending to the top and
+ // bottom edges of the window, respectively.
+ size_t PixelToLine(int y) const;
+
+ // Draws a light border around the inside of the window with the given client
+ // rectangle and DC.
+ void DrawBorder(const RECT& rc, HDC dc);
+
+ // Draws a single run of text with a particular style. Handles both LTR and
+ // RTL text as well as eliding. Returns the width, in pixels, of the string
+ // as it was actually displayed.
+ int DrawString(HDC dc,
+ int x,
+ int y,
+ int max_x,
+ const wchar_t* text,
+ int length,
+ int style,
+ const DrawLineInfo::LineStatus status,
+ const MirroringContext* context,
+ bool text_direction_is_rtl) const;
+
+ // Draws a string from the autocomplete controller which can have specially
+ // marked "match" portions.
+ void DrawMatchFragments(HDC dc,
+ const std::wstring& text,
+ const ACMatchClassifications& classifications,
+ int x,
+ int y,
+ int max_x,
+ DrawLineInfo::LineStatus status) const;
+
+ // Draws one line of the text in the box.
+ void DrawEntry(HDC dc,
+ const RECT& client_rect,
+ size_t line,
+ DrawLineInfo::LineStatus status,
+ bool all_descriptions_empty,
+ bool starred) const;
+
+ // Draws the star at the specified location
+ void DrawStar(HDC dc, int x, int y) const;
+
+ AutocompletePopupModel* model_;
+
+ AutocompleteEditView* edit_view_;
+
+ // Cached GDI information for drawing.
+ DrawLineInfo line_info_;
+
+ // Bitmap for the star. This is owned by the ResourceBundle.
+ SkBitmap* star_;
+
+ // A context used for mirroring regions.
+ scoped_ptr<MirroringContext> mirroring_context_;
+
+ // When hovered_line_ is kNoMatch, this holds the screen coordinates of the
+ // mouse position when hover tracking was turned off. If the mouse moves to a
+ // point over the popup that has different coordinates, hover tracking will be
+ // re-enabled. When hovered_line_ is a valid line, the value here is
+ // out-of-date and should be ignored.
+ CPoint last_hover_coordinates_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutocompletePopupViewWin);
+};
+
+AutocompletePopupViewWin::AutocompletePopupViewWin(
+ AutocompletePopupModel* model,
+ const ChromeFont& font,
+ AutocompleteEditView* edit_view)
: model_(model),
edit_view_(edit_view),
line_info_(font),
@@ -97,7 +371,7 @@ AutocompletePopupView::AutocompletePopupView(AutocompletePopupModel* model,
IDR_CONTENT_STAR_ON)) {
}
-void AutocompletePopupView::InvalidateLine(size_t line) {
+void AutocompletePopupViewWin::InvalidateLine(size_t line) {
RECT rc;
GetClientRect(&rc);
rc.top = LineTopPixel(line);
@@ -105,7 +379,7 @@ void AutocompletePopupView::InvalidateLine(size_t line) {
InvalidateRect(&rc, false);
}
-void AutocompletePopupView::UpdatePopupAppearance() {
+void AutocompletePopupViewWin::UpdatePopupAppearance() {
const AutocompleteResult& result = model_->result();
if (result.empty()) {
// No matches, close any existing popup.
@@ -173,7 +447,7 @@ void AutocompletePopupView::UpdatePopupAppearance() {
// though...
}
-void AutocompletePopupView::OnHoverEnabledOrDisabled(bool disabled) {
+void AutocompletePopupViewWin::OnHoverEnabledOrDisabled(bool disabled) {
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
if (disabled) {
@@ -191,36 +465,36 @@ void AutocompletePopupView::OnHoverEnabledOrDisabled(bool disabled) {
TrackMouseEvent(&tme);
}
-void AutocompletePopupView::OnLButtonDown(UINT keys, const CPoint& point) {
+void AutocompletePopupViewWin::OnLButtonDown(UINT keys, const CPoint& point) {
const size_t new_hovered_line = PixelToLine(point.y);
model_->SetHoveredLine(new_hovered_line);
model_->SetSelectedLine(new_hovered_line, false);
}
-void AutocompletePopupView::OnMButtonDown(UINT keys, const CPoint& point) {
+void AutocompletePopupViewWin::OnMButtonDown(UINT keys, const CPoint& point) {
model_->SetHoveredLine(PixelToLine(point.y));
}
-void AutocompletePopupView::OnLButtonUp(UINT keys, const CPoint& point) {
+void AutocompletePopupViewWin::OnLButtonUp(UINT keys, const CPoint& point) {
OnButtonUp(point, CURRENT_TAB);
}
-void AutocompletePopupView::OnMButtonUp(UINT keys, const CPoint& point) {
+void AutocompletePopupViewWin::OnMButtonUp(UINT keys, const CPoint& point) {
OnButtonUp(point, NEW_BACKGROUND_TAB);
}
-LRESULT AutocompletePopupView::OnMouseActivate(HWND window,
+LRESULT AutocompletePopupViewWin::OnMouseActivate(HWND window,
UINT hit_test,
UINT mouse_message) {
return MA_NOACTIVATE;
}
-void AutocompletePopupView::OnMouseLeave() {
+void AutocompletePopupViewWin::OnMouseLeave() {
// The mouse has left the window, so no line is hovered.
model_->SetHoveredLine(AutocompletePopupModel::kNoMatch);
}
-void AutocompletePopupView::OnMouseMove(UINT keys, const CPoint& point) {
+void AutocompletePopupViewWin::OnMouseMove(UINT keys, const CPoint& point) {
// Track hover when
// (a) The left or middle button is down (the user is interacting via the
// mouse)
@@ -245,7 +519,7 @@ void AutocompletePopupView::OnMouseMove(UINT keys, const CPoint& point) {
}
}
-void AutocompletePopupView::OnPaint(HDC other_dc) {
+void AutocompletePopupViewWin::OnPaint(HDC other_dc) {
const AutocompleteResult& result = model_->result();
DCHECK(!result.empty()); // Shouldn't be drawing an empty popup.
@@ -283,8 +557,8 @@ void AutocompletePopupView::OnPaint(HDC other_dc) {
}
}
-void AutocompletePopupView::OnButtonUp(const CPoint& point,
- WindowOpenDisposition disposition) {
+void AutocompletePopupViewWin::OnButtonUp(const CPoint& point,
+ WindowOpenDisposition disposition) {
const size_t line = PixelToLine(point.y);
const AutocompleteMatch& match = model_->result().match_at(line);
// OpenURL() may close the popup, which will clear the result set and, by
@@ -297,19 +571,19 @@ void AutocompletePopupView::OnButtonUp(const CPoint& point,
is_keyword_hint ? std::wstring() : keyword);
}
-int AutocompletePopupView::LineTopPixel(size_t line) const {
+int AutocompletePopupViewWin::LineTopPixel(size_t line) const {
// The popup has a 1 px top border.
return line_info_.line_height * static_cast<int>(line) + 1;
}
-size_t AutocompletePopupView::PixelToLine(int y) const {
+size_t AutocompletePopupViewWin::PixelToLine(int y) const {
const size_t line = std::max(y - 1, 0) / line_info_.line_height;
return std::min(line, model_->result().size() - 1);
}
// Draws a light border around the inside of the window with the given client
// rectangle and DC.
-void AutocompletePopupView::DrawBorder(const RECT& rc, HDC dc) {
+void AutocompletePopupViewWin::DrawBorder(const RECT& rc, HDC dc) {
HPEN hpen = CreatePen(PS_SOLID, 1, RGB(199, 202, 206));
HGDIOBJ old_pen = SelectObject(dc, hpen);
@@ -326,16 +600,16 @@ void AutocompletePopupView::DrawBorder(const RECT& rc, HDC dc) {
DeleteObject(hpen);
}
-int AutocompletePopupView::DrawString(HDC dc,
- int x,
- int y,
- int max_x,
- const wchar_t* text,
- int length,
- int style,
- const DrawLineInfo::LineStatus status,
- const MirroringContext* context,
- bool text_direction_is_rtl) const {
+int AutocompletePopupViewWin::DrawString(HDC dc,
+ int x,
+ int y,
+ int max_x,
+ const wchar_t* text,
+ int length,
+ int style,
+ const DrawLineInfo::LineStatus status,
+ const MirroringContext* context,
+ bool text_direction_is_rtl) const {
if (length <= 0)
return 0;
@@ -391,7 +665,7 @@ int AutocompletePopupView::DrawString(HDC dc,
return text_x - x;
}
-void AutocompletePopupView::DrawMatchFragments(
+void AutocompletePopupViewWin::DrawMatchFragments(
HDC dc,
const std::wstring& text,
const ACMatchClassifications& classifications,
@@ -496,12 +770,12 @@ void AutocompletePopupView::DrawMatchFragments(
}
}
-void AutocompletePopupView::DrawEntry(HDC dc,
- const RECT& client_rect,
- size_t line,
- DrawLineInfo::LineStatus status,
- bool all_descriptions_empty,
- bool starred) const {
+void AutocompletePopupViewWin::DrawEntry(HDC dc,
+ const RECT& client_rect,
+ size_t line,
+ DrawLineInfo::LineStatus status,
+ bool all_descriptions_empty,
+ bool starred) const {
// Calculate outer bounds of entry, and fill background.
const int top_pixel = LineTopPixel(line);
const RECT rc = {1, top_pixel, client_rect.right - client_rect.left - 1,
@@ -557,7 +831,7 @@ void AutocompletePopupView::DrawEntry(HDC dc,
(line_info_.line_height - star_->height()) / 2 + top_pixel);
}
-void AutocompletePopupView::DrawStar(HDC dc, int x, int y) const {
+void AutocompletePopupViewWin::DrawStar(HDC dc, int x, int y) const {
ChromeCanvas canvas(star_->width(), star_->height(), false);
// Make the background completely transparent.
canvas.drawColor(SK_ColorBLACK, SkPorterDuff::kClear_Mode);
@@ -566,99 +840,14 @@ void AutocompletePopupView::DrawStar(HDC dc, int x, int y) const {
dc, mirroring_context_->GetLeft(x, x + star_->width()), y, NULL);
}
-AutocompletePopupView::DrawLineInfo::DrawLineInfo(const ChromeFont& font) {
- // Create regular and bold fonts.
- regular_font = font.DeriveFont(-1);
- bold_font = regular_font.DeriveFont(0, ChromeFont::BOLD);
-
- // The total padding added to each line (bottom padding is what is
- // left over after DrawEntry() specifies its top offset).
- static const int kTotalLinePadding = 5;
- font_height = std::max(regular_font.height(), bold_font.height());
- line_height = font_height + kTotalLinePadding;
- ave_char_width = regular_font.GetExpectedTextWidth(1);
- ellipsis_width = std::max(regular_font.GetStringWidth(ellipsis_str),
- bold_font.GetStringWidth(ellipsis_str));
-
- // Create background colors.
- background_colors[NORMAL] = GetSysColor(COLOR_WINDOW);
- background_colors[SELECTED] = GetSysColor(COLOR_HIGHLIGHT);
- background_colors[HOVERED] =
- AlphaBlend(background_colors[SELECTED], background_colors[NORMAL], 0x40);
-
- // Create text colors.
- text_colors[NORMAL] = GetSysColor(COLOR_WINDOWTEXT);
- text_colors[HOVERED] = text_colors[NORMAL];
- text_colors[SELECTED] = GetSysColor(COLOR_HIGHLIGHTTEXT);
-
- // Create brushes and url colors.
- const COLORREF dark_url(0x008000);
- const COLORREF light_url(0xd0ffd0);
- for (int i = 0; i < MAX_STATUS_ENTRIES; ++i) {
- // Pick whichever URL color contrasts better.
- const double dark_contrast =
- LuminosityContrast(dark_url, background_colors[i]);
- const double light_contrast =
- LuminosityContrast(light_url, background_colors[i]);
- url_colors[i] = (dark_contrast > light_contrast) ? dark_url : light_url;
-
- brushes[i] = CreateSolidBrush(background_colors[i]);
- }
-}
-
-AutocompletePopupView::DrawLineInfo::~DrawLineInfo() {
- for (int i = 0; i < MAX_STATUS_ENTRIES; ++i)
- DeleteObject(brushes[i]);
-}
-
-// static
-double AutocompletePopupView::DrawLineInfo::LuminosityContrast(
- COLORREF color1,
- COLORREF color2) {
- // This algorithm was adapted from the following text at
- // http://juicystudio.com/article/luminositycontrastratioalgorithm.php :
- //
- // "[Luminosity contrast can be calculated as] (L1+.05) / (L2+.05) where L is
- // luminosity and is defined as .2126*R + .7152*G + .0722B using linearised
- // R, G, and B values. Linearised R (for example) = (R/FS)^2.2 where FS is
- // full scale value (255 for 8 bit color channels). L1 is the higher value
- // (of text or background) and L2 is the lower value.
- //
- // The Gamma correction and RGB constants are derived from the Standard
- // Default Color Space for the Internet (sRGB), and the 0.05 offset is
- // included to compensate for contrast ratios that occur when a value is at
- // or near zero, and for ambient light effects.
- const double l1 = Luminosity(color1);
- const double l2 = Luminosity(color2);
- return (l1 > l2) ? ((l1 + 0.05) / (l2 + 0.05)) : ((l2 + 0.05) / (l1 + 0.05));
-}
+} // namespace
// static
-double AutocompletePopupView::DrawLineInfo::Luminosity(COLORREF color) {
- // See comments in LuminosityContrast().
- const double linearised_r =
- pow(static_cast<double>(GetRValue(color)) / 255.0, 2.2);
- const double linearised_g =
- pow(static_cast<double>(GetGValue(color)) / 255.0, 2.2);
- const double linearised_b =
- pow(static_cast<double>(GetBValue(color)) / 255.0, 2.2);
- return (0.2126 * linearised_r) + (0.7152 * linearised_g) +
- (0.0722 * linearised_b);
-}
-
-COLORREF AutocompletePopupView::DrawLineInfo::AlphaBlend(COLORREF foreground,
- COLORREF background,
- BYTE alpha) {
- if (alpha == 0)
- return background;
- else if (alpha == 0xff)
- return foreground;
-
- return RGB(
- ((GetRValue(foreground) * alpha) +
- (GetRValue(background) * (0xff - alpha))) / 0xff,
- ((GetGValue(foreground) * alpha) +
- (GetGValue(background) * (0xff - alpha))) / 0xff,
- ((GetBValue(foreground) * alpha) +
- (GetBValue(background) * (0xff - alpha))) / 0xff);
+// NOTE: The annoying name CreatePopupView is because otherwise multiple
+// inheritance conflicts with another Create method.
+AutocompletePopupView* AutocompletePopupView::CreatePopupView(
+ AutocompletePopupModel* model,
+ const ChromeFont& font,
+ AutocompleteEditView* edit_view) {
+ return new AutocompletePopupViewWin(model, font, edit_view);
}