Home | History | Annotate | Download | only in panels
      1 // Copyright (c) 2012 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_GTK_PANELS_PANEL_GTK_H_
      6 #define CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_
      7 
      8 #include <gtk/gtk.h>
      9 #include <map>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/timer/timer.h"
     14 #include "chrome/browser/ui/panels/native_panel.h"
     15 #include "chrome/browser/ui/panels/panel_constants.h"
     16 #include "ui/base/gtk/gtk_signal.h"
     17 #include "ui/base/x/active_window_watcher_x_observer.h"
     18 #include "ui/gfx/rect.h"
     19 
     20 class Panel;
     21 class PanelTitlebarGtk;
     22 class PanelDragGtk;
     23 class GtkNativePanelTesting;
     24 
     25 namespace gfx {
     26 class Image;
     27 }
     28 
     29 // An implementation of the native panel in GTK.
     30 class PanelGtk : public NativePanel,
     31                  public ui::ActiveWindowWatcherXObserver {
     32  public:
     33   enum PaintState {
     34     PAINT_AS_ACTIVE,
     35     PAINT_AS_INACTIVE,
     36     PAINT_AS_MINIMIZED,
     37     PAINT_FOR_ATTENTION
     38   };
     39 
     40   PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top);
     41   virtual ~PanelGtk();
     42 
     43   void Init();
     44 
     45   // Overridden from NativePanel.
     46   virtual void ShowPanel() OVERRIDE;
     47   virtual void ShowPanelInactive() OVERRIDE;
     48   virtual gfx::Rect GetPanelBounds() const OVERRIDE;
     49   virtual void SetPanelBounds(const gfx::Rect& bounds) OVERRIDE;
     50   virtual void SetPanelBoundsInstantly(const gfx::Rect& bounds) OVERRIDE;
     51   virtual void ClosePanel() OVERRIDE;
     52   virtual void ActivatePanel() OVERRIDE;
     53   virtual void DeactivatePanel() OVERRIDE;
     54   virtual bool IsPanelActive() const OVERRIDE;
     55   virtual void PreventActivationByOS(bool prevent_activation) OVERRIDE;
     56   virtual gfx::NativeWindow GetNativePanelWindow() OVERRIDE;
     57   virtual void UpdatePanelTitleBar() OVERRIDE;
     58   virtual void UpdatePanelLoadingAnimations(bool should_animate) OVERRIDE;
     59   virtual void PanelWebContentsFocused(content::WebContents* contents) OVERRIDE;
     60   virtual void PanelCut() OVERRIDE;
     61   virtual void PanelCopy() OVERRIDE;
     62   virtual void PanelPaste() OVERRIDE;
     63   virtual void DrawAttention(bool draw_attention) OVERRIDE;
     64   virtual bool IsDrawingAttention() const OVERRIDE;
     65   virtual void HandlePanelKeyboardEvent(
     66       const content::NativeWebKeyboardEvent& event) OVERRIDE;
     67   virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE;
     68   virtual void PanelExpansionStateChanging(
     69       Panel::ExpansionState old_state,
     70       Panel::ExpansionState new_state) OVERRIDE;
     71   virtual void AttachWebContents(content::WebContents* contents) OVERRIDE;
     72   virtual void DetachWebContents(content::WebContents* contents) OVERRIDE;
     73   // These sizes are in screen coordinates.
     74   virtual gfx::Size WindowSizeFromContentSize(
     75       const gfx::Size& content_size) const OVERRIDE;
     76   virtual gfx::Size ContentSizeFromWindowSize(
     77       const gfx::Size& window_size) const OVERRIDE;
     78   virtual int TitleOnlyHeight() const OVERRIDE;
     79   virtual bool IsPanelAlwaysOnTop() const OVERRIDE;
     80   virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE;
     81   virtual void EnableResizeByMouse(bool enable) OVERRIDE;
     82   virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE;
     83   virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE;
     84   virtual void MinimizePanelBySystem() OVERRIDE;
     85   virtual bool IsPanelMinimizedBySystem() const OVERRIDE;
     86   virtual bool IsPanelShownOnActiveDesktop() const OVERRIDE;
     87   virtual void ShowShadow(bool show) OVERRIDE;
     88 
     89   virtual NativePanelTesting* CreateNativePanelTesting() OVERRIDE;
     90 
     91   // Overridden from ActiveWindowWatcherXObserver.
     92   virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
     93 
     94   Panel* panel() const { return panel_.get(); }
     95   PaintState paint_state() const { return paint_state_; }
     96   PanelTitlebarGtk* titlebar() const { return titlebar_.get(); }
     97 
     98  private:
     99   friend class GtkNativePanelTesting;
    100 
    101   // Applies our custom window shape with rounded or non-rounded corners.
    102   void UpdateWindowShape();
    103 
    104   // Checks to see if the mouse pointer at |x|, |y| is over the border of the
    105   // custom frame (a spot that should trigger a window resize). Returns true if
    106   // it should and sets |edge|.
    107   bool GetWindowEdge(int x, int y, GdkWindowEdge* edge) const;
    108 
    109   // Connect/disconnect accelerators for keyboard shortcut support.
    110   void ConnectAccelerators();
    111   void DisconnectAccelerators();
    112 
    113   // Returns the image to paint the frame.
    114   gfx::Image GetFrameBackground() const;
    115 
    116   // Animation when panel is first shown.
    117   void RevealPanel();
    118 
    119   // Creates helper for handling drags if not already created.
    120   void EnsureDragHelperCreated();
    121 
    122   void SetBoundsInternal(const gfx::Rect& bounds);
    123 
    124   void LoadingAnimationCallback();
    125 
    126   // Returns the size of the window frame around the client content area.
    127   gfx::Size GetNonClientFrameSize() const;
    128 
    129   // Invalidate window to force repaint.
    130   void InvalidateWindow();
    131 
    132   // Callback for accelerator activation. |user_data| stores the command id
    133   // of the matched accelerator.
    134   static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
    135                                    GObject* acceleratable,
    136                                    guint keyval,
    137                                    GdkModifierType modifier,
    138                                    void* user_data);
    139 
    140   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMainWindowDeleteEvent,
    141                        GdkEvent*);
    142   CHROMEGTK_CALLBACK_0(PanelGtk, void, OnMainWindowDestroy);
    143   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnConfigure, GdkEventConfigure*);
    144   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnWindowState, GdkEventWindowState*);
    145   // Callback for when the custom frame alignment needs to be redrawn.
    146   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnCustomFrameExpose,
    147                        GdkEventExpose*);
    148   // Key press event callback.
    149   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnKeyPress, GdkEventKey*);
    150   // Mouse move and button press callbacks. If mouse hits titlebar,
    151   // the titlebar gets the event, else the window gets the button press.
    152   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMouseMoveEvent,
    153                        GdkEventMotion*);
    154   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnButtonPressEvent,
    155                        GdkEventButton*);
    156   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean,
    157                        OnTitlebarButtonPressEvent, GdkEventButton*);
    158   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean,
    159                        OnTitlebarButtonReleaseEvent, GdkEventButton*);
    160 
    161   scoped_ptr<Panel> panel_;
    162   gfx::Rect bounds_;
    163 
    164   // True if the panel should always stay on top of other windows.
    165   bool always_on_top_;
    166 
    167   // True after panel has been shown.
    168   bool is_shown_;
    169 
    170   scoped_ptr<PanelDragGtk> drag_helper_;
    171 
    172   // The configure size of the current window, used to figure out whether to
    173   // ignore later configure events. See OnConfigure() for more information.
    174   gfx::Size configure_size_;
    175 
    176   // Indicates different painting state, active, drawing attention or else.
    177   PaintState paint_state_;
    178 
    179   // Indicates that the panel is currently drawing attention.
    180   bool is_drawing_attention_;
    181 
    182   // The timer used to update frames for the Loading Animation.
    183   base::RepeatingTimer<PanelGtk> loading_animation_timer_;
    184 
    185   // The current window cursor.  We set it to a resize cursor when over the
    186   // custom frame border.  We set it to NULL if we want the default cursor.
    187   GdkCursor* frame_cursor_;
    188 
    189   // True if the window manager thinks the window is active.  Not all window
    190   // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case
    191   // this will always be true.
    192   bool is_active_;
    193 
    194   // True if the window manager thinks the window is minimized (iconified).
    195   // Not all window managers support this, in which case this will always be
    196   // false.
    197   bool is_minimized_;
    198 
    199   // Top level window.
    200   GtkWindow* window_;
    201   // GtkAlignment that holds the interior components of the chromium window.
    202   // This is used to draw the custom frame border and content shadow.
    203   GtkWidget* window_container_;
    204   // VBox that holds everything (titlebar, web contents).
    205   GtkWidget* window_vbox_;
    206   // EventBox that holds web contents.
    207   GtkWidget* render_area_event_box_;
    208   // We insert and remove WebContents GtkWidgets into this expanded.
    209   GtkWidget* contents_expanded_;
    210 
    211   // The accelerator group used to handle accelerators, owned by this object.
    212   GtkAccelGroup* accel_group_;
    213 
    214   // The container for the titlebar.
    215   scoped_ptr<PanelTitlebarGtk> titlebar_;
    216 
    217   // Indicates how the window corner should be rendered, rounded or not.
    218   panel::CornerStyle corner_style_;
    219 
    220   DISALLOW_COPY_AND_ASSIGN(PanelGtk);
    221 };
    222 
    223 #endif  // CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_
    224