Home | History | Annotate | Download | only in libgtk2ui
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_
      6 #define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/observer_list.h"
     14 #include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
     15 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h"
     16 #include "chrome/browser/ui/libgtk2ui/libgtk2ui_export.h"
     17 #include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
     18 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
     19 #include "ui/gfx/color_utils.h"
     20 #include "ui/views/linux_ui/linux_ui.h"
     21 #include "ui/views/window/frame_buttons.h"
     22 
     23 typedef struct _GdkColor GdkColor;
     24 typedef struct _GtkBorder GtkBorder;
     25 typedef struct _GtkStyle GtkStyle;
     26 typedef struct _GtkWidget GtkWidget;
     27 
     28 class SkBitmap;
     29 
     30 namespace gfx {
     31 class Image;
     32 }
     33 
     34 namespace libgtk2ui {
     35 class Gtk2Border;
     36 class Gtk2KeyBindingsHandler;
     37 class Gtk2SignalRegistrar;
     38 class GConfListener;
     39 
     40 // Interface to GTK2 desktop features.
     41 //
     42 class Gtk2UI : public views::LinuxUI {
     43  public:
     44   Gtk2UI();
     45   virtual ~Gtk2UI();
     46 
     47   typedef base::Callback<ui::NativeTheme*(aura::Window* window)>
     48       NativeThemeGetter;
     49 
     50   // Setters used by GConfListener:
     51   void SetWindowButtonOrdering(
     52     const std::vector<views::FrameButton>& leading_buttons,
     53     const std::vector<views::FrameButton>& trailing_buttons);
     54   void SetNonClientMiddleClickAction(NonClientMiddleClickAction action);
     55 
     56   // Draws the GTK button border for state |gtk_state| onto a bitmap.
     57   SkBitmap DrawGtkButtonBorder(int gtk_state,
     58                                bool focused,
     59                                int width,
     60                                int height) const;
     61 
     62   // ui::LinuxInputMethodContextFactory:
     63   virtual scoped_ptr<ui::LinuxInputMethodContext> CreateInputMethodContext(
     64       ui::LinuxInputMethodContextDelegate* delegate) const OVERRIDE;
     65 
     66   // gfx::LinuxFontDelegate:
     67   virtual bool UseAntialiasing() const OVERRIDE;
     68   virtual gfx::FontRenderParams::Hinting GetHintingStyle() const OVERRIDE;
     69   virtual gfx::FontRenderParams::SubpixelRendering
     70       GetSubpixelRenderingStyle() const OVERRIDE;
     71   virtual std::string GetDefaultFontName() const OVERRIDE;
     72 
     73   // ui::LinuxShellDialog:
     74   virtual ui::SelectFileDialog* CreateSelectFileDialog(
     75       ui::SelectFileDialog::Listener* listener,
     76       ui::SelectFilePolicy* policy) const OVERRIDE;
     77 
     78   // ui::LinuxUI:
     79   virtual void Initialize() OVERRIDE;
     80   virtual gfx::Image GetThemeImageNamed(int id) const OVERRIDE;
     81   virtual bool GetColor(int id, SkColor* color) const OVERRIDE;
     82   virtual bool HasCustomImage(int id) const OVERRIDE;
     83   virtual SkColor GetFocusRingColor() const OVERRIDE;
     84   virtual SkColor GetThumbActiveColor() const OVERRIDE;
     85   virtual SkColor GetThumbInactiveColor() const OVERRIDE;
     86   virtual SkColor GetTrackColor() const OVERRIDE;
     87   virtual SkColor GetActiveSelectionBgColor() const OVERRIDE;
     88   virtual SkColor GetActiveSelectionFgColor() const OVERRIDE;
     89   virtual SkColor GetInactiveSelectionBgColor() const OVERRIDE;
     90   virtual SkColor GetInactiveSelectionFgColor() const OVERRIDE;
     91   virtual double GetCursorBlinkInterval() const OVERRIDE;
     92   virtual ui::NativeTheme* GetNativeTheme(aura::Window* window) const OVERRIDE;
     93   virtual void SetNativeThemeOverride(const NativeThemeGetter& callback)
     94       OVERRIDE;
     95   virtual bool GetDefaultUsesSystemTheme() const OVERRIDE;
     96   virtual void SetDownloadCount(int count) const OVERRIDE;
     97   virtual void SetProgressFraction(float percentage) const OVERRIDE;
     98   virtual bool IsStatusIconSupported() const OVERRIDE;
     99   virtual scoped_ptr<views::StatusIconLinux> CreateLinuxStatusIcon(
    100       const gfx::ImageSkia& image,
    101       const base::string16& tool_tip) const OVERRIDE;
    102   virtual gfx::Image GetIconForContentType(
    103       const std::string& content_type, int size) const OVERRIDE;
    104   virtual scoped_ptr<views::Border> CreateNativeBorder(
    105       views::LabelButton* owning_button,
    106       scoped_ptr<views::LabelButtonBorder> border) OVERRIDE;
    107   virtual void AddWindowButtonOrderObserver(
    108       views::WindowButtonOrderObserver* observer) OVERRIDE;
    109   virtual void RemoveWindowButtonOrderObserver(
    110       views::WindowButtonOrderObserver* observer) OVERRIDE;
    111   virtual bool UnityIsRunning() OVERRIDE;
    112   virtual NonClientMiddleClickAction GetNonClientMiddleClickAction() OVERRIDE;
    113   virtual void NotifyWindowManagerStartupComplete() OVERRIDE;
    114 
    115   // ui::TextEditKeybindingDelegate:
    116   virtual bool MatchEvent(
    117       const ui::Event& event,
    118       std::vector<ui::TextEditCommandAuraLinux>* commands) OVERRIDE;
    119 
    120  private:
    121   typedef std::map<int, SkColor> ColorMap;
    122   typedef std::map<int, color_utils::HSL> TintMap;
    123   typedef std::map<int, gfx::Image> ImageCache;
    124 
    125   // This method returns the colors webkit will use for the scrollbars. When no
    126   // colors are specified by the GTK+ theme, this function averages of the
    127   // thumb part and of the track colors.
    128   void GetScrollbarColors(GdkColor* thumb_active_color,
    129                           GdkColor* thumb_inactive_color,
    130                           GdkColor* track_color);
    131 
    132   // Extracts colors and tints from the GTK theme, both for the
    133   // ThemeService interface and the colors we send to webkit.
    134   void LoadGtkValues();
    135 
    136   // Reads in explicit theme frame colors from the ChromeGtkFrame style class
    137   // or generates them per our fallback algorithm.
    138   GdkColor BuildFrameColors(GtkStyle* frame_style);
    139 
    140   // Sets the underlying theme colors/tints from a GTK color.
    141   void SetThemeColorFromGtk(int id, const GdkColor* color);
    142   void SetThemeTintFromGtk(int id, const GdkColor* color);
    143 
    144   // Creates and returns a frame color, either using |gtk_base| verbatim if
    145   // non-NULL, or tinting |base| with |tint|. Also sets |color_id| and
    146   // |tint_id| to the returned color.
    147   GdkColor BuildAndSetFrameColor(const GdkColor* base,
    148                                  const GdkColor* gtk_base,
    149                                  const color_utils::HSL& tint,
    150                                  int color_id,
    151                                  int tint_id);
    152 
    153   // Lazily generates each bitmap used in the gtk theme.
    154   SkBitmap GenerateGtkThemeBitmap(int id) const;
    155 
    156   // Creates a GTK+ version of IDR_THEME_FRAME. Instead of tinting, this
    157   // creates a theme configurable gradient ending with |color_id| at the
    158   // bottom, and |gradient_name| at the top if that color is specified in the
    159   // theme.
    160   SkBitmap GenerateFrameImage(int color_id,
    161                               const char* gradient_name) const;
    162 
    163   // Takes the base frame image |base_id| and tints it with |tint_id|.
    164   SkBitmap GenerateTabImage(int base_id) const;
    165 
    166   // Tints an icon based on tint.
    167   SkBitmap GenerateTintedIcon(int base_id,
    168                               const color_utils::HSL& tint) const;
    169 
    170   // Renders a GTK icon as a SkBitmap, with prelight/active border if
    171   // appropriate.
    172   SkBitmap GenerateGTKIcon(int base_id) const;
    173 
    174   // Renders a GTK button border the size of the image |sizing_idr| in
    175   // |gtk_state|.
    176   SkBitmap GenerateToolbarBezel(int gtk_state, int sizing_idr) const;
    177 
    178   // Returns the tint for buttons that contrasts with the normal window
    179   // background color.
    180   void GetNormalButtonTintHSL(color_utils::HSL* tint) const;
    181 
    182   // Returns a tint that's the color of the current normal text in an entry.
    183   void GetNormalEntryForegroundHSL(color_utils::HSL* tint) const;
    184 
    185   // Returns a tint that's the color of the current highlighted text in an
    186   // entry.
    187   void GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const;
    188 
    189   // Frees all calculated images and color data.
    190   void ClearAllThemeData();
    191 
    192   // Handles signal from GTK that our theme has been changed.
    193   CHROMEGTK_CALLBACK_1(Gtk2UI, void, OnStyleSet, GtkStyle*);
    194 
    195   GtkWidget* fake_window_;
    196   GtkWidget* fake_frame_;
    197   OwnedWidgetGtk fake_label_;
    198   OwnedWidgetGtk fake_entry_;
    199 
    200   // Tracks all the signals we have connected to on various widgets.
    201   scoped_ptr<Gtk2SignalRegistrar> signals_;
    202 
    203   // Tints and colors calculated by LoadGtkValues() that are given to the
    204   // caller while |use_gtk_| is true.
    205   ColorMap colors_;
    206   TintMap tints_;
    207 
    208   // Colors used to tint certain icons.
    209   color_utils::HSL button_tint_;
    210   color_utils::HSL entry_tint_;
    211   color_utils::HSL selected_entry_tint_;
    212 
    213   // Colors that we pass to WebKit. These are generated each time the theme
    214   // changes.
    215   SkColor focus_ring_color_;
    216   SkColor thumb_active_color_;
    217   SkColor thumb_inactive_color_;
    218   SkColor track_color_;
    219   SkColor active_selection_bg_color_;
    220   SkColor active_selection_fg_color_;
    221   SkColor inactive_selection_bg_color_;
    222   SkColor inactive_selection_fg_color_;
    223 
    224 #if defined(USE_GCONF)
    225   // Currently, the only source of window button configuration. This will
    226   // change if we ever have to support XFCE's configuration system or KDE's.
    227   scoped_ptr<GConfListener> gconf_listener_;
    228 #endif  // defined(USE_GCONF)
    229 
    230   // If either of these vectors are non-empty, they represent the current
    231   // window button configuration.
    232   std::vector<views::FrameButton> leading_buttons_;
    233   std::vector<views::FrameButton> trailing_buttons_;
    234 
    235   scoped_ptr<Gtk2KeyBindingsHandler> key_bindings_handler_;
    236 
    237   // Objects to notify when the window frame button order changes.
    238   ObserverList<views::WindowButtonOrderObserver> observer_list_;
    239 
    240   // Whether we should lower the window on a middle click to the non client
    241   // area.
    242   NonClientMiddleClickAction middle_click_action_;
    243 
    244   // Image cache of lazily created images.
    245   mutable ImageCache gtk_images_;
    246 
    247   // Used to override the native theme for a window. If no override is provided
    248   // or the callback returns NULL, Gtk2UI will default to a NativeThemeGtk2
    249   // instance.
    250   NativeThemeGetter native_theme_overrider_;
    251 
    252   DISALLOW_COPY_AND_ASSIGN(Gtk2UI);
    253 };
    254 
    255 }  // namespace libgtk2ui
    256 
    257 // Access point to the GTK2 desktop system. This should be the only symbol that
    258 // is exported in the library; everything else should be used through the
    259 // interface, because eventually this .so will be loaded through dlopen at
    260 // runtime so our main binary can conditionally load GTK2 or GTK3 or EFL or
    261 // QT or whatever.
    262 LIBGTK2UI_EXPORT views::LinuxUI* BuildGtk2UI();
    263 
    264 #endif  // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_
    265