Skip to content

Commit

Permalink
Combobox arrow theming for aura linux
Browse files Browse the repository at this point in the history
See bug for before and after screenshots.

BUG=384164

Review URL: https://codereview.chromium.org/337613002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277612 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
estade@chromium.org committed Jun 17, 2014
1 parent 49337f0 commit 8a52512
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 45 deletions.
12 changes: 1 addition & 11 deletions chrome/browser/ui/libgtk2ui/gtk2_border.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <gtk/gtk.h>

#include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h"
#include "third_party/skia/include/effects/SkLerpXfermode.h"
#include "ui/base/theme_provider.h"
Expand All @@ -27,17 +28,6 @@ namespace {

const int kNumberOfFocusedStates = 2;

GtkStateType GetGtkState(ui::NativeTheme::State state) {
switch (state) {
case ui::NativeTheme::kDisabled: return GTK_STATE_INSENSITIVE;
case ui::NativeTheme::kHovered: return GTK_STATE_PRELIGHT;
case ui::NativeTheme::kNormal: return GTK_STATE_NORMAL;
case ui::NativeTheme::kPressed: return GTK_STATE_ACTIVE;
case ui::NativeTheme::kMaxState: NOTREACHED() << "Unknown state: " << state;
}
return GTK_STATE_NORMAL;
}

class ButtonImageSkiaSource : public gfx::ImageSkiaSource {
public:
ButtonImageSkiaSource(const Gtk2UI* gtk2_ui,
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/ui/libgtk2ui/gtk2_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ void Gtk2UI::GetScrollbarColors(GdkColor* thumb_active_color,
// Draw scrollbar thumb part and track into offscreen image
const int kWidth = 100;
const int kHeight = 20;
GtkStyle* style = gtk_rc_get_style(scrollbar);
GtkStyle* style = gtk_rc_get_style(scrollbar);
GdkWindow* gdk_window = gtk_widget_get_window(window);
GdkPixmap* pm = gdk_pixmap_new(gdk_window, kWidth, kHeight, -1);
GdkRectangle rect = { 0, 0, kWidth, kHeight };
Expand Down
11 changes: 11 additions & 0 deletions chrome/browser/ui/libgtk2ui/gtk2_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,15 @@ void ClearAuraTransientParent(GtkWidget* dialog) {
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL);
}

GtkStateType GetGtkState(ui::NativeTheme::State state) {
switch (state) {
case ui::NativeTheme::kDisabled: return GTK_STATE_INSENSITIVE;
case ui::NativeTheme::kHovered: return GTK_STATE_PRELIGHT;
case ui::NativeTheme::kNormal: return GTK_STATE_NORMAL;
case ui::NativeTheme::kPressed: return GTK_STATE_ACTIVE;
case ui::NativeTheme::kMaxState: NOTREACHED() << "Unknown state: " << state;
}
return GTK_STATE_NORMAL;
}

} // namespace libgtk2ui
5 changes: 5 additions & 0 deletions chrome/browser/ui/libgtk2ui/gtk2_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <gtk/gtk.h>
#include <string>

#include "ui/native_theme/native_theme.h"

class SkBitmap;

namespace aura {
Expand Down Expand Up @@ -53,6 +55,9 @@ aura::Window* GetAuraTransientParent(GtkWidget* dialog);
// Clears the transient parent for |dialog|.
void ClearAuraTransientParent(GtkWidget* dialog);

// Converts a NativeTheme state to a GtkStateType.
GtkStateType GetGtkState(ui::NativeTheme::State state);

} // namespace libgtk2ui

#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UTIL_H_
68 changes: 67 additions & 1 deletion chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <gtk/gtk.h>

#include "chrome/browser/ui/libgtk2ui/chrome_gtk_menu_subclasses.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/path.h"
Expand Down Expand Up @@ -121,6 +122,33 @@ NativeThemeGtk2::~NativeThemeGtk2() {
fake_menu_.Destroy();
}

gfx::Size NativeThemeGtk2::GetPartSize(Part part,
State state,
const ExtraParams& extra) const {
if (part == kComboboxArrow)
return gfx::Size(12, 12);

return gfx::Size();
}

void NativeThemeGtk2::Paint(SkCanvas* canvas,
Part part,
State state,
const gfx::Rect& rect,
const ExtraParams& extra) const {
if (rect.IsEmpty())
return;

switch (part) {
case kComboboxArrow:
PaintComboboxArrow(canvas, GetGtkState(state), rect);
return;

default:
NativeThemeBase::Paint(canvas, part, state, rect, extra);
}
}

SkColor NativeThemeGtk2::GetSystemColor(ColorId color_id) const {
return GdkColorToSkColor(GetSystemGdkColor(color_id));
}
Expand Down Expand Up @@ -364,7 +392,7 @@ GtkStyle* NativeThemeGtk2::GetEntryStyle() const {
if (!fake_entry_.get()) {
fake_entry_.Own(gtk_entry_new());

// The fake entry needs to be in the window so it can be realized sow e can
// The fake entry needs to be in the window so it can be realized so we can
// use the computed parts of the style.
gtk_container_add(GTK_CONTAINER(GetRealizedWindow()), fake_entry_.get());
gtk_widget_realize(fake_entry_.get());
Expand Down Expand Up @@ -420,4 +448,42 @@ GtkStyle* NativeThemeGtk2::GetMenuItemStyle() const {
return gtk_rc_get_style(fake_menu_item_);
}

void NativeThemeGtk2::PaintComboboxArrow(SkCanvas* canvas,
GtkStateType state,
const gfx::Rect& rect) const {
GdkPixmap* pm = gdk_pixmap_new(gtk_widget_get_window(GetRealizedWindow()),
rect.width(),
rect.height(),
-1);
// Paint the background.
gtk_paint_flat_box(GetWindowStyle(),
pm,
state,
GTK_SHADOW_NONE,
NULL,
GetRealizedWindow(),
NULL, 0, 0, rect.width(), rect.height());
gtk_paint_arrow(GetWindowStyle(),
pm,
state,
GTK_SHADOW_NONE,
NULL,
GetRealizedWindow(),
NULL,
GTK_ARROW_DOWN,
true,
0, 0, rect.width(), rect.height());
GdkPixbuf* pb = gdk_pixbuf_get_from_drawable(NULL,
pm,
gdk_drawable_get_colormap(pm),
0, 0,
0, 0,
rect.width(), rect.height());
SkBitmap arrow = GdkPixbufToImageSkia(pb);
canvas->drawBitmap(arrow, rect.x(), rect.y());

g_object_unref(pb);
g_object_unref(pm);
}

} // namespace libgtk2ui
16 changes: 14 additions & 2 deletions chrome/browser/ui/libgtk2ui/native_theme_gtk2.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
#ifndef CHROME_BROWSER_UI_LIBGTK2UI_NATIVE_THEME_GTK2_H_
#define CHROME_BROWSER_UI_LIBGTK2UI_NATIVE_THEME_GTK2_H_

#include <gtk/gtk.h>

#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
#include "ui/native_theme/native_theme_base.h"

typedef struct _GdkColor GdkColor;
typedef struct _GtkStyle GtkStyle;
typedef struct _GtkWidget GtkWidget;

namespace libgtk2ui {

Expand All @@ -22,6 +22,14 @@ class NativeThemeGtk2 : public ui::NativeThemeBase {
static NativeThemeGtk2* instance();

// Overridden from ui::NativeThemeBase:
virtual gfx::Size GetPartSize(Part part,
State state,
const ExtraParams& extra) const OVERRIDE;
virtual void Paint(SkCanvas* canvas,
Part part,
State state,
const gfx::Rect& rect,
const ExtraParams& extra) const OVERRIDE;
virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE;
virtual void PaintMenuPopupBackground(
SkCanvas* canvas,
Expand Down Expand Up @@ -51,6 +59,10 @@ class NativeThemeGtk2 : public ui::NativeThemeBase {
GtkStyle* GetMenuStyle() const;
GtkStyle* GetMenuItemStyle() const;

void PaintComboboxArrow(SkCanvas* canvas,
GtkStateType state,
const gfx::Rect& rect) const;

mutable GtkWidget* fake_window_;
mutable GtkWidget* fake_tooltip_;
mutable OwnedWidgetGtk fake_entry_;
Expand Down
21 changes: 21 additions & 0 deletions ui/native_theme/common_theme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/rect.h"
Expand Down Expand Up @@ -122,6 +123,10 @@ gfx::Size CommonThemeGetPartSize(NativeTheme::Part part,
const NativeTheme::ExtraParams& extra) {
gfx::Size size;
switch (part) {
case NativeTheme::kComboboxArrow:
return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_MENU_DROPARROW).Size();

case NativeTheme::kMenuCheck: {
const gfx::ImageSkia* check =
ui::ResourceBundle::GetSharedInstance().GetImageNamed(
Expand All @@ -136,6 +141,12 @@ gfx::Size CommonThemeGetPartSize(NativeTheme::Part part,
return size;
}

void CommonThemePaintComboboxArrow(SkCanvas* canvas, const gfx::Rect& rect) {
gfx::ImageSkia* arrow = ui::ResourceBundle::GetSharedInstance().
GetImageSkiaNamed(IDR_MENU_DROPARROW);
CommonThemeCreateCanvas(canvas)->DrawImageInt(*arrow, rect.x(), rect.y());
}

void CommonThemePaintMenuSeparator(
SkCanvas* canvas,
const gfx::Rect& rect,
Expand Down Expand Up @@ -189,4 +200,14 @@ void CommonThemePaintMenuItemBackground(SkCanvas* canvas,
canvas->drawRect(gfx::RectToSkRect(rect), paint);
}

// static
scoped_ptr<gfx::Canvas> CommonThemeCreateCanvas(SkCanvas* sk_canvas) {
// TODO(pkotwicz): Do something better and don't infer device
// scale factor from canvas scale.
SkMatrix m = sk_canvas->getTotalMatrix();
float device_scale = static_cast<float>(SkScalarAbs(m.getScaleX()));
return scoped_ptr<gfx::Canvas>(
gfx::Canvas::CreateCanvasWithoutScaling(sk_canvas, device_scale));
}

} // namespace ui
13 changes: 13 additions & 0 deletions ui/native_theme/common_theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
#ifndef UI_NATIVE_THEME_COMMON_THEME_H_
#define UI_NATIVE_THEME_COMMON_THEME_H_

#include "base/memory/scoped_ptr.h"
#include "ui/native_theme/native_theme.h"

class SkCanvas;

namespace gfx {
class Canvas;
}

namespace ui {

// Drawing code that is common for all platforms.
Expand All @@ -23,6 +28,10 @@ gfx::Size NATIVE_THEME_EXPORT CommonThemeGetPartSize(
NativeTheme::State state,
const NativeTheme::ExtraParams& extra);

void NATIVE_THEME_EXPORT CommonThemePaintComboboxArrow(
SkCanvas* canvas,
const gfx::Rect& rect);

void NATIVE_THEME_EXPORT CommonThemePaintMenuSeparator(
SkCanvas* canvas,
const gfx::Rect& rect,
Expand All @@ -39,6 +48,10 @@ void NATIVE_THEME_EXPORT CommonThemePaintMenuItemBackground(
NativeTheme::State state,
const gfx::Rect& rect);

// Creates a gfx::Canvas wrapping an SkCanvas.
scoped_ptr<gfx::Canvas> NATIVE_THEME_EXPORT CommonThemeCreateCanvas(
SkCanvas* sk_canvas);

} // namespace ui

#endif // UI_NATIVE_THEME_COMMON_THEME_H_
1 change: 1 addition & 0 deletions ui/native_theme/native_theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class NATIVE_THEME_EXPORT NativeTheme {
public:
// The part to be painted / sized.
enum Part {
kComboboxArrow,
kCheckbox,
kInnerSpinButton,
kMenuList,
Expand Down
6 changes: 3 additions & 3 deletions ui/native_theme/native_theme_aura.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void NativeThemeAura::PaintPainter(NineImagePainter* painter,
SkCanvas* sk_canvas,
const gfx::Rect& rect) const {
DCHECK(painter);
scoped_ptr<gfx::Canvas> canvas(CreateCanvas(sk_canvas));
scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
painter->Paint(canvas.get(), rect);
}

Expand All @@ -286,7 +286,7 @@ void NativeThemeAura::PaintDualPainter(
const gfx::Rect& rect,
State state) const {
DCHECK(dual_painter);
scoped_ptr<gfx::Canvas> canvas(CreateCanvas(sk_canvas));
scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
dual_painter->fill_painter->Paint(
canvas.get(), rect, dual_painter->fill_alphas[state]);
dual_painter->stroke_painter->Paint(
Expand All @@ -301,7 +301,7 @@ void NativeThemeAura::PaintDualPainterTransition(
State endState,
double progress) const {
DCHECK(dual_painter);
scoped_ptr<gfx::Canvas> canvas(CreateCanvas(sk_canvas));
scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
uint8 fill_alpha = dual_painter->fill_alphas[startState] +
(dual_painter->fill_alphas[endState] -
dual_painter->fill_alphas[startState]) *
Expand Down
22 changes: 10 additions & 12 deletions ui/native_theme/native_theme_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/common_theme.h"

namespace {

Expand Down Expand Up @@ -89,6 +90,10 @@ namespace ui {
gfx::Size NativeThemeBase::GetPartSize(Part part,
State state,
const ExtraParams& extra) const {
gfx::Size size = CommonThemeGetPartSize(part, state, extra);
if (!size.IsEmpty())
return size;

switch (part) {
// Please keep these in the order of NativeTheme::Part.
case kCheckbox:
Expand Down Expand Up @@ -191,6 +196,9 @@ void NativeThemeBase::Paint(SkCanvas* canvas,

switch (part) {
// Please keep these in the order of NativeTheme::Part.
case kComboboxArrow:
CommonThemePaintComboboxArrow(canvas, rect);
break;
case kCheckbox:
PaintCheckbox(canvas, state, rect, extra.button);
break;
Expand Down Expand Up @@ -277,16 +285,6 @@ NativeThemeBase::NativeThemeBase()
NativeThemeBase::~NativeThemeBase() {
}

// static
scoped_ptr<gfx::Canvas> NativeThemeBase::CreateCanvas(SkCanvas* sk_canvas) {
// TODO(pkotwicz): Do something better and don't infer device
// scale factor from canvas scale.
SkMatrix m = sk_canvas->getTotalMatrix();
float device_scale = static_cast<float>(SkScalarAbs(m.getScaleX()));
return scoped_ptr<gfx::Canvas>(
gfx::Canvas::CreateCanvasWithoutScaling(sk_canvas, device_scale));
}

void NativeThemeBase::PaintArrowButton(
SkCanvas* canvas,
const gfx::Rect& rect, Part direction, State state) const {
Expand Down Expand Up @@ -984,7 +982,7 @@ void NativeThemeBase::DrawImageInt(
SkCanvas* sk_canvas, const gfx::ImageSkia& image,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h) const {
scoped_ptr<gfx::Canvas> canvas(CreateCanvas(sk_canvas));
scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
canvas->DrawImageInt(image, src_x, src_y, src_w, src_h,
dest_x, dest_y, dest_w, dest_h, true);
}
Expand All @@ -993,7 +991,7 @@ void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas,
const gfx::ImageSkia& image,
int src_x, int src_y, float tile_scale_x, float tile_scale_y,
int dest_x, int dest_y, int w, int h) const {
scoped_ptr<gfx::Canvas> canvas(CreateCanvas(sk_canvas));
scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
canvas->TileImageInt(image, src_x, src_y, tile_scale_x,
tile_scale_y, dest_x, dest_y, w, h);
}
Expand Down
3 changes: 0 additions & 3 deletions ui/native_theme/native_theme_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ class NATIVE_THEME_EXPORT NativeThemeBase : public NativeTheme {
NativeThemeBase();
virtual ~NativeThemeBase();

// Creates a gfx::Canvas wrapping an SkCanvas.
static scoped_ptr<gfx::Canvas> CreateCanvas(SkCanvas* sk_canvas);

// Draw the arrow. Used by scrollbar and inner spin button.
virtual void PaintArrowButton(
SkCanvas* gc,
Expand Down
Loading

0 comments on commit 8a52512

Please sign in to comment.