15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/panels/panel_titlebar_gtk.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/custom_button.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/panels/panel_gtk.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_compat.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_utils_gtk.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding around the titlebar.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelTitlebarPaddingTop = 4;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelTitlebarPaddingBottom = 8;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelTitlebarPaddingLeft = 6;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelTitlebarPaddingRight = 0;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Padding around the box containing icon and title.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelIconTitlePaddingTop = 3;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelIconTitlePaddingBottom = 0;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelIconTitlePaddingLeft = 0;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelIconTitlePaddingRight = 0;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Spacing between buttons of panel's titlebar.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPanelButtonSpacing = 5;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Spacing between the icon and the title text.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPanelIconTitleSpacing = 9;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Color used to draw title text under default theme.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Markup used to paint the title with the desired font.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kTitleMarkupPrefix =
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "<span face='Arial' weight='bold' size='11264'>";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kTitleMarkupSuffix = "</span>";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelTitlebarGtk::PanelTitlebarGtk(PanelGtk* panel_gtk)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : panel_gtk_(panel_gtk),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      container_(NULL),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      titlebar_right_buttons_vbox_(NULL),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      titlebar_right_buttons_hbox_(NULL),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_(NULL),
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      title_(NULL) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelTitlebarGtk::~PanelTitlebarGtk() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::Init() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_ = gtk_event_box_new();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_set_name(container_, "chrome-panel-titlebar");
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We use an alignment to control the titlebar paddings.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* container_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(container_), container_alignment);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_alignment_set_padding(GTK_ALIGNMENT(container_alignment),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kPanelTitlebarPaddingTop,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kPanelTitlebarPaddingBottom,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kPanelTitlebarPaddingLeft,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kPanelTitlebarPaddingRight);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a container box.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* container_hbox = gtk_hbox_new(FALSE, 0);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(container_alignment), container_hbox);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add minimize/restore and close buttons. Panel buttons are always placed
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the right part of the titlebar.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_right_buttons_vbox_,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   FALSE, FALSE, 0);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildButtons();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add an extra alignment to control the paddings for icon and title.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GtkWidget* icon_title_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_container_add(GTK_CONTAINER(container_hbox), icon_title_alignment);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_alignment_set_padding(GTK_ALIGNMENT(icon_title_alignment),
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            kPanelIconTitlePaddingTop,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            kPanelIconTitlePaddingBottom,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            kPanelIconTitlePaddingLeft,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            kPanelIconTitlePaddingRight);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add hbox for holding icon and title.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* icon_title_hbox = gtk_hbox_new(FALSE, kPanelIconTitleSpacing);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_container_add(GTK_CONTAINER(icon_title_alignment), icon_title_hbox);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add icon. We use the app logo as a placeholder image so the title doesn't
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // jump around.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_ = gtk_image_new_from_pixbuf(rb.GetNativeImageNamed(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PRODUCT_LOGO_16, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_object_set_data(G_OBJECT(icon_), "left-align-popup",
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    reinterpret_cast<void*>(true));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(icon_title_hbox), icon_, FALSE, FALSE, 0);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add title.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_ = gtk_label_new(NULL);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_label_set_ellipsize(GTK_LABEL(title_), PANGO_ELLIPSIZE_END);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_misc_set_alignment(GTK_MISC(title_), 0.0, 0.5);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(icon_title_hbox), title_, TRUE, TRUE, 0);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateTitleAndIcon();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateTextColor();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show_all(container_);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor PanelTitlebarGtk::GetTextColor() const {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kTitleTextDefaultColor;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::BuildButtons() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  minimize_button_.reset(CreateButton(panel::MINIMIZE_BUTTON));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restore_button_.reset(CreateButton(panel::RESTORE_BUTTON));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close_button_.reset(CreateButton(panel::CLOSE_BUTTON));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We control visibility of minimize and restore buttons.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_set_no_show_all(minimize_button_->widget(), TRUE);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_set_no_show_all(restore_button_->widget(), TRUE);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now show the correct widgets in the two hierarchies.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateMinimizeRestoreButtonVisibility();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomDrawButton* PanelTitlebarGtk::CreateButton(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::TitlebarButtonType button_type) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int normal_image_id = -1;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pressed_image_id = -1;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hover_image_id = -1;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tooltip_id = -1;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetButtonResources(button_type, &normal_image_id, &pressed_image_id,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     &hover_image_id, &tooltip_id);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomDrawButton* button = new CustomDrawButton(normal_image_id,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  pressed_image_id,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  hover_image_id,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  0);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_widget_set_size_request(button->widget(),
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              panel::kPanelButtonSize,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              panel::kPanelButtonSize);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(button->widget(), "clicked",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnButtonClickedThunk), this);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip_id);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_set_tooltip_text(button->widget(),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              localized_tooltip.c_str());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* box = GetButtonHBox();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return button;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::GetButtonResources(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::TitlebarButtonType button_type,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* normal_image_id,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* pressed_image_id,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* hover_image_id,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* tooltip_id) const {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (button_type) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::CLOSE_BUTTON:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *normal_image_id = IDR_PANEL_CLOSE;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *pressed_image_id = IDR_PANEL_CLOSE_C;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *hover_image_id = IDR_PANEL_CLOSE_H;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *tooltip_id = IDS_PANEL_CLOSE_TOOLTIP;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::MINIMIZE_BUTTON:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *normal_image_id = IDR_PANEL_MINIMIZE;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *pressed_image_id = IDR_PANEL_MINIMIZE_C;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *hover_image_id = IDR_PANEL_MINIMIZE_H;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *tooltip_id = IDS_PANEL_MINIMIZE_TOOLTIP;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::RESTORE_BUTTON:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *normal_image_id = IDR_PANEL_RESTORE;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *pressed_image_id = IDR_PANEL_RESTORE_C;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *hover_image_id = IDR_PANEL_RESTORE_H;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *tooltip_id = IDS_PANEL_RESTORE_TOOLTIP;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GtkWidget* PanelTitlebarGtk::GetButtonHBox() {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!titlebar_right_buttons_hbox_) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We put the minimize/restore/close buttons in a vbox so they are top
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // aligned (up to padding) and don't vertically stretch.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    titlebar_right_buttons_hbox_ = gtk_hbox_new(FALSE, kPanelButtonSpacing);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_box_pack_start(GTK_BOX(titlebar_right_buttons_vbox_),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       titlebar_right_buttons_hbox_, FALSE, FALSE, 0);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return titlebar_right_buttons_hbox_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::UpdateTitleAndIcon() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string title_text =
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UTF16ToUTF8(panel_gtk_->panel()->GetWindowTitle());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the markup to show the title in the desired font.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gchar* escaped_title_text = g_markup_escape_text(title_text.c_str(), -1);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gchar* title_text_with_markup = g_strconcat(kTitleMarkupPrefix,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              escaped_title_text,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kTitleMarkupSuffix,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              NULL);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_label_set_markup(GTK_LABEL(title_), title_text_with_markup);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_free(escaped_title_text);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_free(title_text_with_markup);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update icon from the web contents.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* web_contents = panel_gtk_->panel()->GetWebContents();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateThrobber(web_contents);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::UpdateThrobber(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents && web_contents->IsLoading()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdkPixbuf* icon_pixbuf =
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        throbber_.GetNextFrame(web_contents->IsWaitingForResponse());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Image icon = panel_gtk_->panel()->GetCurrentPageIcon();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (icon.IsEmpty()) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Fallback to the Chromium icon if the page has no icon.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_image_set_from_pixbuf(GTK_IMAGE(icon_),
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon.ToGdkPixbuf());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    throbber_.Reset();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::UpdateTextColor() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkColor text_color = gfx::SkColorToGdkColor(GetTextColor());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::SetLabelColor(title_, &text_color);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::UpdateMinimizeRestoreButtonVisibility() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Panel* panel = panel_gtk_->panel();
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_widget_set_visible(minimize_button_->widget(),
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         panel->CanShowMinimizeButton());
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gtk_widget_set_visible(restore_button_->widget(),
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         panel->CanShowRestoreButton());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::OnButtonClicked(GtkWidget* button) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Panel* panel = panel_gtk_->panel();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (close_button_->widget() == button) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel->Close();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkEvent* event = gtk_get_current_event();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(event && event->type == GDK_BUTTON_RELEASE);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (minimize_button_->widget() == button) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel->OnMinimizeButtonClicked(
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (event->button.state & GDK_CONTROL_MASK) ?
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            panel::APPLY_TO_ALL : panel::NO_MODIFIER);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (restore_button_->widget() == button) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel->OnRestoreButtonClicked(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (event->button.state & GDK_CONTROL_MASK) ?
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            panel::APPLY_TO_ALL : panel::NO_MODIFIER);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    panel->Activate();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_event_free(event);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelTitlebarGtk::SendEnterNotifyToCloseButtonIfUnderMouse() {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!close_button())
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint x;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gint y;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkAllocation widget_allocation = close_button()->WidgetAllocation();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_get_pointer(GTK_WIDGET(close_button()->widget()), &x, &y);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect button_rect(0, 0, widget_allocation.width,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        widget_allocation.height);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!button_rect.Contains(x, y)) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Mouse is not over the close button.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create and emit an enter-notify-event on close button.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GValue return_value;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return_value.g_type = G_TYPE_BOOLEAN;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_value_set_boolean(&return_value, false);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkEvent* event = gdk_event_new(GDK_ENTER_NOTIFY);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.window =
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_button_get_event_window(GTK_BUTTON(close_button()->widget()));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.send_event = FALSE;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.subwindow = gtk_widget_get_window(close_button()->widget());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.time = gtk_util::XTimeNow();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.x = x;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.y = y;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.x_root = widget_allocation.x;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.y_root = widget_allocation.y;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.mode = GDK_CROSSING_NORMAL;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.detail = GDK_NOTIFY_ANCESTOR;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.focus = true;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->crossing.state = 0;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_emit_by_name(GTK_OBJECT(close_button()->widget()),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        "enter-notify-event", event,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &return_value);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GtkWidget* PanelTitlebarGtk::widget() const {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return container_;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
331