summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/panels/panel_overflow_browsertest.cc121
-rw-r--r--chrome/browser/ui/panels/panel_overflow_indicator_gtk.cc135
-rw-r--r--chrome/browser/ui/panels/panel_overflow_indicator_gtk.h14
3 files changed, 206 insertions, 64 deletions
diff --git a/chrome/browser/ui/panels/panel_overflow_browsertest.cc b/chrome/browser/ui/panels/panel_overflow_browsertest.cc
index 71bd4ed..3c011a934 100644
--- a/chrome/browser/ui/panels/panel_overflow_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_overflow_browsertest.cc
@@ -204,14 +204,14 @@ class PanelOverflowBrowserTest : public BasePanelBrowserTest {
// TODO(dimich): remove the guard when overflow indicator is implemented on
// other platforms.
-#if defined(OS_WIN)
-#define MAYBE_CreateMoreOverflowPanels CreateMoreOverflowPanels
-#define MAYBE_OverflowIndicatorCount OverflowIndicatorCount
-#define MAYBE_DrawOverflowAttention DrawOverflowAttention
-#else
+#if defined(OS_MACOSX)
#define MAYBE_CreateMoreOverflowPanels DISABLED_CreateMoreOverflowPanels
#define MAYBE_OverflowIndicatorCount DISABLED_OverflowIndicatorCount
#define MAYBE_DrawOverflowAttention DISABLED_DrawOverflowAttention
+#else
+#define MAYBE_CreateMoreOverflowPanels CreateMoreOverflowPanels
+#define MAYBE_OverflowIndicatorCount OverflowIndicatorCount
+#define MAYBE_DrawOverflowAttention DrawOverflowAttention
#endif
IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, CheckPanelProperties) {
@@ -1451,7 +1451,7 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_OverflowIndicatorCount) {
// docked: P0, P1, P2
// overflow: P3, P4, P5
const int panel_widths[] = {
- 250, 250, 210, // docked
+ 250, 200, 250, // docked
250, 250, 260 // overflow
};
std::vector<Panel*> panels = CreateOverflowPanels(3, 3, panel_widths);
@@ -1523,15 +1523,16 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_OverflowIndicatorCount) {
EXPECT_FALSE(IsPanelVisible(panels[10]));
EXPECT_EQ(3, overflow_strip->overflow_indicator()->GetCount());
- // Activating a big overflow panel will cause 2 docked panels to move to the
- // oevrflow area and also get the top visible overflow panel bumped to the
- // overflow-on-overflow.
+ // Widen a docked panel to bump a panel to overflow and also get the
+ // top visible overflow panel bumped to the overflow-to-overflow.
// Expect the overflow indicator count gets increased by 1.
- // docked: P0, P5
- // overflow: P1, P2, P6, (P7, P8, P9, P10)
- panels[5]->Activate();
- WaitForPanelActiveState(panels[5], SHOW_AS_ACTIVE);
- WaitForLayoutModeChanged(panels[5], PanelStrip::DOCKED);
+ // docked: P0, P1
+ // overflow: P2, P5, P6, (P7, P8, P9, P10)
+ gfx::Size larger_size = panels[1]->GetBounds().size();
+ larger_size.Enlarge(50, 50);
+ panel_manager->ResizePanel(panels[1], larger_size);
+ WaitForBoundsAnimationFinished(panels[1]);
+ WaitForLayoutModeChanged(panels[2], PanelStrip::IN_OVERFLOW);
EXPECT_TRUE(IsPanelVisible(panels[6]));
EXPECT_FALSE(IsPanelVisible(panels[7]));
EXPECT_FALSE(IsPanelVisible(panels[8]));
@@ -1543,6 +1544,13 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_OverflowIndicatorCount) {
}
IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_DrawOverflowAttention) {
+ // IceWM may activate another panel when an overflow-on-overflow
+ // panel is hidden. It happens to pick the panel we want to draw attention
+ // to, but drawing attention on an active panel is a no-op, so this test
+ // fails under IceWM.
+ if (SkipTestIfIceWM())
+ return;
+
PanelManager* panel_manager = PanelManager::GetInstance();
DockedPanelStrip* docked_strip = panel_manager->docked_strip();
OverflowPanelStrip* overflow_strip = panel_manager->overflow_strip();
@@ -1553,7 +1561,7 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_DrawOverflowAttention) {
// The panels enclosed in parentheses are hidden.
const int panel_widths[] = {
100, 210, 210, 210, // docked
- 210, 260, 210, // overflow
+ 210, 210, 210, // overflow
210, 210, 210, // overflow-on-overflow on shrunk
210, 210 // overflow-on-overflow on expanded
};
@@ -1572,19 +1580,18 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_DrawOverflowAttention) {
EXPECT_TRUE(panels[5]->IsDrawingAttention());
EXPECT_FALSE(overflow_indicator->IsDrawingAttention());
- // Activating this overflow panel will clear its attention.
+ // Stop drawing attention for the visible overflow panel.
// Expect no impact to the overflow indicator.
- // docked: P0, P1, P2, P5
- // overflow: P3, P4, P6, (P7, P8, P9, P10, P11)
- panels[5]->Activate();
- WaitForPanelActiveState(panels[5], SHOW_AS_ACTIVE);
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, P6, (P7, P8, P9, P10, P11)
+ panels[5]->FlashFrame(false);
EXPECT_FALSE(panels[5]->IsDrawingAttention());
EXPECT_FALSE(overflow_indicator->IsDrawingAttention());
// Draw attention for an overflow-on-overflow panel.
// Expect the overflow indicator is showing attention.
- // docked: P0, P1, P2, P5
- // overflow: P3, P4, P6, (P7, *P8, P9, P10, P11)
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, P6, (P7, *P8, P9, P10, P11)
EXPECT_FALSE(panels[8]->IsDrawingAttention());
panels[8]->FlashFrame(true);
EXPECT_TRUE(panels[8]->IsDrawingAttention());
@@ -1592,64 +1599,64 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, MAYBE_DrawOverflowAttention) {
// Draw attention for another overflow-on-overflow panel.
// Expect the overflow indicator is still showing attention.
- // docked: P0, P1, P2, P5
- // overflow: P3, P4, P6, (P7, *P8, P9, *P10, P11)
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, P6, (P7, *P8, P9, *P10, P11)
EXPECT_FALSE(panels[10]->IsDrawingAttention());
panels[10]->FlashFrame(true);
EXPECT_TRUE(panels[10]->IsDrawingAttention());
EXPECT_TRUE(overflow_indicator->IsDrawingAttention());
- // Stop drawing attention for an overflow-on-overflow panel by activating it.
+ // Stop drawing attention for one overflow-on-overflow panel.
// Expect the overflow indicator is still showing attention.
- // docked: P0, P1, P2, P8
- // overflow: P5, P3, P4, (P6, P7, P9, *P10, P11)
- panels[8]->Activate();
- WaitForPanelActiveState(panels[8], SHOW_AS_ACTIVE);
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, P6, (P7, P8, P9, *P10, P11)
+ panels[8]->FlashFrame(false);
EXPECT_FALSE(panels[8]->IsDrawingAttention());
EXPECT_TRUE(overflow_indicator->IsDrawingAttention());
- // Stop drawing attention for another overflow-on-overflow panel by activating
- // it. Expect the overflow indicator is not showing attention.
- // docked: P0, P1, P2, P10
- // overflow: P8, P5, P3, (P4, P6, P7, P9, P11)
- panels[10]->Activate();
- WaitForPanelActiveState(panels[10], SHOW_AS_ACTIVE);
+ // Stop drawing attention for the other overflow-on-overflow panel.
+ // Expect the overflow indicator is not showing attention.
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, P6, (P7, P8, P9, P10, P11)
+ panels[10]->FlashFrame(false);
EXPECT_FALSE(panels[10]->IsDrawingAttention());
EXPECT_FALSE(overflow_indicator->IsDrawingAttention());
// Draw attention for the top overflow panel.
// Expect no impact to the overflow indicator.
- // docked: P0, P1, P2, P10
- // overflow: P8, P5, *P3, (P4, P6, P7, P9, P11)
- EXPECT_TRUE(IsPanelVisible(panels[3]));
- EXPECT_FALSE(panels[3]->IsDrawingAttention());
- panels[3]->FlashFrame(true);
- EXPECT_TRUE(panels[3]->IsDrawingAttention());
+ // docked: P0, P1, P2, P3
+ // overflow: P4, P5, *P6, (P7, P8, P9, P10, P11)
+ EXPECT_TRUE(IsPanelVisible(panels[6]));
+ EXPECT_FALSE(panels[6]->IsDrawingAttention());
+ panels[6]->FlashFrame(true);
+ EXPECT_TRUE(panels[6]->IsDrawingAttention());
EXPECT_FALSE(overflow_indicator->IsDrawingAttention());
- // Activating a big overflow panel will cause 2 docked panels to move to the
- // overflow area and also get the top visible overflow panel bumped to the
- // overflow-on-overflow.
+ // Widen a panel in the dock to bump a panel to the overflow area
+ // and also get the top visible overflow panel bumped to overflow-on-overflow.
// Expect the overflow indicator is showing attention.
- // docked: P0, P1, P5
- // overflow: P2, P10, P8, (*P3, P4, P6, P7, P9, P11)
- panels[5]->Activate();
- WaitForPanelActiveState(panels[5], SHOW_AS_ACTIVE);
- WaitForLayoutModeChanged(panels[5], PanelStrip::DOCKED);
+ // docked: P0, P1, P2,
+ // overflow: P3, P4, P5, (*P6, P7, P8, P9, P10, P11)
+ gfx::Size larger_size = panels[0]->GetBounds().size();
+ larger_size.Enlarge(150, 50);
+ panel_manager->ResizePanel(panels[0], larger_size);
+ WaitForLayoutModeChanged(panels[3], PanelStrip::IN_OVERFLOW);
EXPECT_EQ(3, docked_strip->num_panels());
EXPECT_EQ(9, overflow_strip->num_panels());
- EXPECT_FALSE(IsPanelVisible(panels[3]));
- EXPECT_TRUE(panels[3]->IsDrawingAttention());
+ WaitForBoundsAnimationFinished(panels[6]);
+ EXPECT_FALSE(IsPanelVisible(panels[6]));
+ EXPECT_TRUE(panels[6]->IsDrawingAttention());
EXPECT_TRUE(overflow_indicator->IsDrawingAttention());
- // Close an overflow panel that would move the first oveflow-on-overflow panel
- // to become visible. Expect the overflow indicator is not showing attention.
- // docked: P0, P1, P5
- // overflow: P2, P10, P3, (P4, P6, P7, P9, P11)
- CloseWindowAndWait(panels[8]->browser());
+ // Close an overflow panel that would cause the first oveflow-on-overflow
+ // panel to become visible. Expect the overflow indicator is no longer
+ // showing attention.
+ // docked: P0, P1, P2,
+ // overflow: P4, P5, *P6, (P7, P8, P9, P10, P11)
+ CloseWindowAndWait(panels[3]->browser());
EXPECT_EQ(3, docked_strip->num_panels());
EXPECT_EQ(8, overflow_strip->num_panels());
- EXPECT_TRUE(panels[3]->IsDrawingAttention());
+ EXPECT_TRUE(panels[6]->IsDrawingAttention());
EXPECT_FALSE(overflow_indicator->IsDrawingAttention());
panel_manager->CloseAll();
diff --git a/chrome/browser/ui/panels/panel_overflow_indicator_gtk.cc b/chrome/browser/ui/panels/panel_overflow_indicator_gtk.cc
index 42e451b..196fec5 100644
--- a/chrome/browser/ui/panels/panel_overflow_indicator_gtk.cc
+++ b/chrome/browser/ui/panels/panel_overflow_indicator_gtk.cc
@@ -1,43 +1,166 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/panels/panel_overflow_indicator_gtk.h"
+#include <string>
+
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "chrome/browser/ui/gtk/rounded_window.h"
+#include "ui/base/gtk/gtk_hig_constants.h"
+
+namespace {
+
+// The height in pixels of the widget to show the plus count.
+const int kWidgetHeight = 15;
+
+// Rounded corner size.
+const int kRoundedCornerSize = 4;
+
+// Metrics for the indicator text.
+const int kTextFontSize = 10 * PANGO_SCALE;
+const GdkColor kTextColor = ui::kGdkWhite;
+
+// Gradient colors used to draw the background in normal mode.
+const GdkColor kNormalBackgroundColorStart =
+ GDK_COLOR_RGB(0x77, 0x77, 0x77);
+const GdkColor kNormalBackgroundColorEnd =
+ GDK_COLOR_RGB(0x55, 0x55, 0x55);
+
+// Gradient colors used to draw the background in attention mode.
+const GdkColor kAttentionBackgroundColorStart =
+ GDK_COLOR_RGB(0xFF, 0xAB, 0x57);
+const GdkColor kAttentionBackgroundColorEnd =
+ GDK_COLOR_RGB(0xF5, 0x93, 0x38);
+
+} // namespace
+
PanelOverflowIndicator* PanelOverflowIndicator::Create() {
return new PanelOverflowIndicatorGtk();
}
-PanelOverflowIndicatorGtk::PanelOverflowIndicatorGtk() {
+PanelOverflowIndicatorGtk::PanelOverflowIndicatorGtk()
+ : count_(0),
+ is_drawing_attention_(false) {
+ window_ = gtk_window_new(GTK_WINDOW_POPUP);
+
+ title_ = gtk_label_new(NULL);
+ PangoAttrList* attributes = pango_attr_list_new();
+ pango_attr_list_insert(attributes,
+ pango_attr_weight_new(PANGO_WEIGHT_BOLD));
+ pango_attr_list_insert(attributes,
+ pango_attr_foreground_new(kTextColor.red,
+ kTextColor.green,
+ kTextColor.blue));
+ pango_attr_list_insert(attributes,
+ pango_attr_size_new_absolute(kTextFontSize));
+ gtk_label_set_attributes(GTK_LABEL(title_), attributes);
+ pango_attr_list_unref(attributes);
+ gtk_container_add(GTK_CONTAINER(window_), title_);
+ gtk_widget_show(title_);
+
+ gtk_util::ActAsRoundedWindow(window_, GdkColor(), kRoundedCornerSize,
+ gtk_util::ROUNDED_TOP_RIGHT,
+ gtk_util::BORDER_NONE);
+
+ g_signal_connect(window_, "expose-event",
+ G_CALLBACK(OnExposeThunk), this);
}
PanelOverflowIndicatorGtk::~PanelOverflowIndicatorGtk() {
+ gtk_widget_destroy(window_);
}
int PanelOverflowIndicatorGtk::GetHeight() const {
- return 0;
+ return kWidgetHeight;
}
gfx::Rect PanelOverflowIndicatorGtk::GetBounds() const {
- return gfx::Rect();
+ return bounds_;
}
void PanelOverflowIndicatorGtk::SetBounds(const gfx::Rect& bounds) {
+ if (bounds_ == bounds)
+ return;
+ bounds_ = bounds;
+ gtk_window_move(GTK_WINDOW(window_), bounds.x(), bounds.y());
+ gtk_window_resize(GTK_WINDOW(window_), bounds.width(), bounds.height());
}
int PanelOverflowIndicatorGtk::GetCount() const {
- return 0;
+ return count_;
}
void PanelOverflowIndicatorGtk::SetCount(int count) {
+ if (count_ == count)
+ return;
+ count_ = count;
+
+ if (count_ > 0) {
+ std::string title_text = "+" + base::IntToString(count_);
+ gtk_label_set_text(GTK_LABEL(title_), title_text.c_str());
+
+ gtk_widget_show(window_);
+ } else {
+ gtk_widget_hide(window_);
+ }
}
void PanelOverflowIndicatorGtk::DrawAttention() {
+ if (is_drawing_attention_)
+ return;
+ is_drawing_attention_ = true;
+ gtk_widget_queue_draw(window_);
}
void PanelOverflowIndicatorGtk::StopDrawingAttention() {
+ if (!is_drawing_attention_)
+ return;
+ is_drawing_attention_ = false;
+ gtk_widget_queue_draw(window_);
}
bool PanelOverflowIndicatorGtk::IsDrawingAttention() const {
- return false;
+ return is_drawing_attention_;
+}
+
+gboolean PanelOverflowIndicatorGtk::OnExpose(GtkWidget* widget,
+ GdkEventExpose* event) {
+ cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget));
+ gdk_cairo_rectangle(cr, &event->area);
+ cairo_clip(cr);
+
+ // Draw background color.
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(widget, &allocation);
+ cairo_pattern_t* pattern = cairo_pattern_create_linear(
+ allocation.x, allocation.y,
+ allocation.x + allocation.width, allocation.y);
+
+ const GdkColor* color_start;
+ const GdkColor* color_end;
+ if (is_drawing_attention_) {
+ color_start = &kAttentionBackgroundColorStart;
+ color_end = &kAttentionBackgroundColorEnd;
+ } else {
+ color_start = &kNormalBackgroundColorStart;
+ color_end = &kNormalBackgroundColorEnd;
+ }
+
+ cairo_pattern_add_color_stop_rgb(pattern, 0.0,
+ color_start->red / 65535.0,
+ color_start->green / 65535.0,
+ color_start->blue / 65535.0);
+ cairo_pattern_add_color_stop_rgb(pattern, 1.0,
+ color_end->red / 65535.0,
+ color_end->green / 65535.0,
+ color_end->blue / 65535.0);
+
+ cairo_set_source(cr, pattern);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ return FALSE;
}
diff --git a/chrome/browser/ui/panels/panel_overflow_indicator_gtk.h b/chrome/browser/ui/panels/panel_overflow_indicator_gtk.h
index 9f75c53..76a1b92 100644
--- a/chrome/browser/ui/panels/panel_overflow_indicator_gtk.h
+++ b/chrome/browser/ui/panels/panel_overflow_indicator_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,8 +8,11 @@
#include "chrome/browser/ui/panels/panel_overflow_indicator.h"
+#include <gtk/gtk.h>
+
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "ui/base/gtk/gtk_signal.h"
class PanelOverflowIndicatorGtk : public PanelOverflowIndicator {
public:
@@ -27,6 +30,15 @@ class PanelOverflowIndicatorGtk : public PanelOverflowIndicator {
virtual bool IsDrawingAttention() const OVERRIDE;
private:
+ CHROMEGTK_CALLBACK_1(PanelOverflowIndicatorGtk, gboolean, OnExpose,
+ GdkEventExpose*);
+
+ int count_;
+ bool is_drawing_attention_;
+ GtkWidget* window_;
+ GtkWidget* title_;
+ gfx::Rect bounds_;
+
DISALLOW_COPY_AND_ASSIGN(PanelOverflowIndicatorGtk);
};