Skip to content

Commit

Permalink
Support active / inactive frame colors for app window frames.
Browse files Browse the repository at this point in the history
This adds two new options to the FrameOptions field, activeColor and
inactiveColor. These cannot be set if color is also set.

BUG=339558

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267505 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
benwells@chromium.org committed May 1, 2014
1 parent d3c0222 commit 09f494a
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 41 deletions.
12 changes: 11 additions & 1 deletion apps/app_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,17 @@ void AppWindow::GetSerializedState(base::DictionaryValue* properties) const {
properties->SetBoolean("maximized", native_app_window_->IsMaximized());
properties->SetBoolean("alwaysOnTop", IsAlwaysOnTop());
properties->SetBoolean("hasFrameColor", native_app_window_->HasFrameColor());
properties->SetInteger("frameColor", native_app_window_->FrameColor());

// These properties are undocumented and are to enable testing. Alpha is
// removed to
// make the values easier to check.
SkColor transparent_white = ~SK_ColorBLACK;
properties->SetInteger(
"activeFrameColor",
native_app_window_->ActiveFrameColor() & transparent_white);
properties->SetInteger(
"inactiveFrameColor",
native_app_window_->InactiveFrameColor() & transparent_white);

gfx::Rect content_bounds = GetClientBounds();
gfx::Size content_min_size = native_app_window_->GetContentMinimumSize();
Expand Down
3 changes: 2 additions & 1 deletion apps/app_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ class AppWindow : public content::NotificationObserver,
Frame frame;

bool has_frame_color;
SkColor frame_color;
SkColor active_frame_color;
SkColor inactive_frame_color;
bool transparent_background; // Only supported on ash.

// The initial content/inner bounds specification (excluding any window
Expand Down
3 changes: 2 additions & 1 deletion apps/ui/native_app_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class NativeAppWindow : public ui::BaseWindow,

// Returns information about the window's frame.
virtual bool HasFrameColor() const = 0;
virtual SkColor FrameColor() const = 0;
virtual SkColor ActiveFrameColor() const = 0;
virtual SkColor InactiveFrameColor() const = 0;

// Returns the difference between the window bounds (including titlebar and
// borders) and the content bounds, if any.
Expand Down
15 changes: 8 additions & 7 deletions apps/ui/views/app_window_frame_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ const char AppWindowFrameView::kViewClassName[] =
AppWindowFrameView::AppWindowFrameView(views::Widget* widget,
NativeAppWindow* window,
bool draw_frame,
const SkColor& frame_color)
const SkColor& active_frame_color,
const SkColor& inactive_frame_color)
: widget_(widget),
window_(window),
draw_frame_(draw_frame),
frame_color_(frame_color),
active_frame_color_(active_frame_color),
inactive_frame_color_(inactive_frame_color),
close_button_(NULL),
maximize_button_(NULL),
restore_button_(NULL),
Expand Down Expand Up @@ -232,8 +234,6 @@ void AppWindowFrameView::GetWindowMask(const gfx::Size& size,
// We got nothing to say about no window mask.
}

// views::View implementation.

gfx::Size AppWindowFrameView::GetPreferredSize() {
gfx::Size pref = widget_->client_view()->GetPreferredSize();
gfx::Rect bounds(0, 0, pref.width(), pref.height());
Expand Down Expand Up @@ -308,7 +308,10 @@ void AppWindowFrameView::OnPaint(gfx::Canvas* canvas) {
SkPaint paint;
paint.setAntiAlias(false);
paint.setStyle(SkPaint::kFill_Style);
paint.setColor(frame_color_);
if (widget_->IsActive())
paint.setColor(active_frame_color_);
else
paint.setColor(inactive_frame_color_);
gfx::Path path;
path.moveTo(0, 0);
path.lineTo(width(), 0);
Expand Down Expand Up @@ -350,8 +353,6 @@ gfx::Size AppWindowFrameView::GetMaximumSize() {
return max_size;
}

// views::ButtonListener implementation.

void AppWindowFrameView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
DCHECK(draw_frame_);
Expand Down
6 changes: 4 additions & 2 deletions apps/ui/views/app_window_frame_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class AppWindowFrameView : public views::NonClientFrameView,
AppWindowFrameView(views::Widget* widget,
NativeAppWindow* window,
bool draw_frame,
const SkColor& frame_color);
const SkColor& active_frame_color,
const SkColor& inactive_frame_color);
virtual ~AppWindowFrameView();

void Init();
Expand Down Expand Up @@ -90,7 +91,8 @@ class AppWindowFrameView : public views::NonClientFrameView,
views::Widget* widget_;
NativeAppWindow* window_;
bool draw_frame_;
SkColor frame_color_;
SkColor active_frame_color_;
SkColor inactive_frame_color_;
views::ImageButton* close_button_;
views::ImageButton* maximize_button_;
views::ImageButton* restore_button_;
Expand Down
8 changes: 7 additions & 1 deletion apps/ui/views/native_app_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,13 @@ bool NativeAppWindowViews::IsFrameless() const { return frameless_; }

bool NativeAppWindowViews::HasFrameColor() const { return false; }

SkColor NativeAppWindowViews::FrameColor() const { return SK_ColorBLACK; }
SkColor NativeAppWindowViews::ActiveFrameColor() const {
return SK_ColorBLACK;
}

SkColor NativeAppWindowViews::InactiveFrameColor() const {
return SK_ColorBLACK;
}

gfx::Insets NativeAppWindowViews::GetFrameInsets() const {
if (frameless_)
Expand Down
3 changes: 2 additions & 1 deletion apps/ui/views/native_app_window_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ class NativeAppWindowViews : public NativeAppWindow,
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool IsFrameless() const OVERRIDE;
virtual bool HasFrameColor() const OVERRIDE;
virtual SkColor FrameColor() const OVERRIDE;
virtual SkColor ActiveFrameColor() const OVERRIDE;
virtual SkColor InactiveFrameColor() const OVERRIDE;
virtual gfx::Insets GetFrameInsets() const OVERRIDE;
virtual void HideWithApp() OVERRIDE;
virtual void ShowWithApp() OVERRIDE;
Expand Down
34 changes: 27 additions & 7 deletions chrome/browser/extensions/api/app_window/app_window_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ const char kInvalidWindowId[] =
const char kInvalidColorSpecification[] =
"The color specification could not be parsed.";
const char kInvalidChannelForFrameOptions[] =
"frameOptions is only available in dev channel.";
"Frame options are only available in dev channel.";
const char kColorWithFrameNone[] = "Windows with no frame cannot have a color.";
const char kInactiveColorWithoutColor[] =
"frame.inactiveColor must be used with frame.color.";
const char kConflictingBoundsOptions[] =
"The $1 property cannot be specified for both inner and outer bounds.";
} // namespace app_window_constants
Expand Down Expand Up @@ -451,13 +453,30 @@ bool AppWindowCreateFunction::GetFrameOptions(
return false;
}

if (image_util::ParseCSSColorString(*options.frame->as_frame_options->color,
&create_params->frame_color)) {
create_params->has_frame_color = true;
return true;
if (!image_util::ParseCSSColorString(
*options.frame->as_frame_options->color,
&create_params->active_frame_color)) {
error_ = app_window_constants::kInvalidColorSpecification;
return false;
}

create_params->has_frame_color = true;
create_params->inactive_frame_color = create_params->active_frame_color;

if (options.frame->as_frame_options->inactive_color.get()) {
if (!image_util::ParseCSSColorString(
*options.frame->as_frame_options->inactive_color,
&create_params->inactive_frame_color)) {
error_ = app_window_constants::kInvalidColorSpecification;
return false;
}
}

error_ = app_window_constants::kInvalidColorSpecification;
return true;
}

if (options.frame->as_frame_options->inactive_color.get()) {
error_ = app_window_constants::kInactiveColorWithoutColor;
return false;
}

Expand All @@ -473,7 +492,8 @@ void AppWindowCreateFunction::UpdateFrameOptionsForChannel(
// TODO(benwells): Remove this code once we get agreement to use the new
// native style frame.
create_params->has_frame_color = true;
create_params->frame_color = SK_ColorWHITE;
create_params->active_frame_color = SK_ColorWHITE;
create_params->inactive_frame_color = SK_ColorWHITE;
}
#endif
}
Expand Down
3 changes: 2 additions & 1 deletion chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ class NativeAppWindowCocoa : public apps::NativeAppWindow,
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool IsFrameless() const OVERRIDE;
virtual bool HasFrameColor() const OVERRIDE;
virtual SkColor FrameColor() const OVERRIDE;
virtual SkColor ActiveFrameColor() const OVERRIDE;
virtual SkColor InactiveFrameColor() const OVERRIDE;
virtual gfx::Insets GetFrameInsets() const OVERRIDE;

// These are used to simulate Mac-style hide/show. Since windows can be hidden
Expand Down
7 changes: 6 additions & 1 deletion chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,12 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move;
return false;
}

SkColor NativeAppWindowCocoa::FrameColor() const {
SkColor NativeAppWindowCocoa::ActiveFrameColor() const {
// TODO(benwells): Implement this.
return SkColor();
}

SkColor NativeAppWindowCocoa::InactiveFrameColor() const {
// TODO(benwells): Implement this.
return SkColor();
}
Expand Down
23 changes: 18 additions & 5 deletions chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate,
ChromeNativeAppWindowViews::ChromeNativeAppWindowViews()
: is_fullscreen_(false),
has_frame_color_(false),
frame_color_(SK_ColorBLACK) {}
active_frame_color_(SK_ColorBLACK),
inactive_frame_color_(SK_ColorBLACK) {
}

ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {}

Expand Down Expand Up @@ -347,8 +349,12 @@ ChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() {

apps::AppWindowFrameView*
ChromeNativeAppWindowViews::CreateNonStandardAppFrame() {
apps::AppWindowFrameView* frame = new apps::AppWindowFrameView(
widget(), this, has_frame_color_, frame_color_);
apps::AppWindowFrameView* frame =
new apps::AppWindowFrameView(widget(),
this,
has_frame_color_,
active_frame_color_,
inactive_frame_color_);
frame->Init();
#if defined(USE_ASH)
// For Aura windows on the Ash desktop the sizes are different and the user
Expand Down Expand Up @@ -669,7 +675,13 @@ bool ChromeNativeAppWindowViews::HasFrameColor() const {
return has_frame_color_;
}

SkColor ChromeNativeAppWindowViews::FrameColor() const { return frame_color_; }
SkColor ChromeNativeAppWindowViews::ActiveFrameColor() const {
return active_frame_color_;
}

SkColor ChromeNativeAppWindowViews::InactiveFrameColor() const {
return inactive_frame_color_;
}

// NativeAppWindowViews implementation.

Expand All @@ -678,7 +690,8 @@ void ChromeNativeAppWindowViews::InitializeWindow(
const AppWindow::CreateParams& create_params) {
DCHECK(widget());
has_frame_color_ = create_params.has_frame_color;
frame_color_ = create_params.frame_color;
active_frame_color_ = create_params.active_frame_color;
inactive_frame_color_ = create_params.inactive_frame_color;
if (create_params.window_type == AppWindow::WINDOW_TYPE_PANEL ||
create_params.window_type == AppWindow::WINDOW_TYPE_V1_PANEL) {
InitializePanelWindow(create_params);
Expand Down
6 changes: 4 additions & 2 deletions chrome/browser/ui/views/apps/chrome_native_app_window_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ class ChromeNativeAppWindowViews : public apps::NativeAppWindowViews,
virtual void UpdateBadgeIcon() OVERRIDE;
virtual void UpdateShape(scoped_ptr<SkRegion> region) OVERRIDE;
virtual bool HasFrameColor() const OVERRIDE;
virtual SkColor FrameColor() const OVERRIDE;
virtual SkColor ActiveFrameColor() const OVERRIDE;
virtual SkColor InactiveFrameColor() const OVERRIDE;

// NativeAppWindowViews implementation.
virtual void InitializeWindow(
Expand All @@ -90,7 +91,8 @@ class ChromeNativeAppWindowViews : public apps::NativeAppWindowViews,
scoped_ptr<SkRegion> shape_;

bool has_frame_color_;
SkColor frame_color_;
SkColor active_frame_color_;
SkColor inactive_frame_color_;
gfx::Size preferred_size_;

// The class that registers for keyboard shortcuts for extension commands.
Expand Down
18 changes: 16 additions & 2 deletions chrome/common/extensions/api/app_window.idl
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,22 @@ namespace app.window {
// nested elements.<br>
DOMString? type;
// Allows the frame color to be set. Frame coloring is only available if the
// frame type is <code>chrome</code>.
// frame type is <code>chrome</code>.<br>
// Frame coloring is experimental and only available in dev channel.
DOMString? color;
// Allows the frame color of the window when active to be set. Frame
// coloring is only available if the frame type is <code>chrome</code>.<br>
// Frame coloring is only available if the frame type is
// <code>chrome</code>.<br>
// Frame coloring is experimental and only available in dev channel.
DOMString? activeColor;
// Allows the frame color of the window when inactive to be set differently
// to the active color. Frame
// coloring is only available if the frame type is <code>chrome</code>.<br>
// <code>inactiveColor</code> must be used in conjunction with <code>
// color</code>.<br>
// Frame coloring is experimental and only available in dev channel.
DOMString? inactiveColor;
};

// State of a window: normal, fullscreen, maximized, minimized.
Expand Down Expand Up @@ -329,7 +342,8 @@ namespace app.window {

// Accessors for testing.
[nodoc] boolean hasFrameColor;
[nodoc] long frameColor;
[nodoc] long activeFrameColor;
[nodoc] long inactiveFrameColor;

// Set whether the window should stay above most other windows. Requires the
// <code>"app.window.alwaysOnTop"</code> permission.
Expand Down
13 changes: 10 additions & 3 deletions chrome/renderer/resources/extensions/app_window_custom_bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,14 @@ appWindow.registerCustomHook(function(bindingsAPI) {
return appWindowData.hasFrameColor;
}});

Object.defineProperty(AppWindow.prototype, 'frameColor', {get: function() {
return appWindowData.frameColor;
Object.defineProperty(AppWindow.prototype, 'activeFrameColor',
{get: function() {
return appWindowData.activeFrameColor;
}});

Object.defineProperty(AppWindow.prototype, 'inactiveFrameColor',
{get: function() {
return appWindowData.inactiveFrameColor;
}});

appWindowData = {
Expand Down Expand Up @@ -284,7 +290,8 @@ appWindow.registerCustomHook(function(bindingsAPI) {
maximized: params.maximized,
alwaysOnTop: params.alwaysOnTop,
hasFrameColor: params.hasFrameColor,
frameColor: params.frameColor
activeFrameColor: params.activeFrameColor,
inactiveFrameColor: params.inactiveFrameColor
};
currentAppWindow = new AppWindow;
});
Expand Down
Loading

0 comments on commit 09f494a

Please sign in to comment.