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