1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_CHROMEOS_FRAME_PANEL_CONTROLLER_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_CHROMEOS_FRAME_PANEL_CONTROLLER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "third_party/cros/chromeos_wm_ipc_enums.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/x/x11_util.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/button.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BrowserView;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SkBitmap;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef unsigned long XID;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace base {
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Time;
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace views {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ImageButton;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ImageView;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Label;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MouseEvent;
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Widget;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Controls interactions with the WM for popups / panels.
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PanelController {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum State {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    INITIAL,
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPANDED,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MINIMIZED,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Delegate to control panel's appearance and behavior.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class Delegate {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Retrieves the title string of the panel.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual string16 GetPanelTitle() = 0;
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Retrieves the icon to use in the panel's titlebar.
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual SkBitmap GetPanelIcon() = 0;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Can the panel be closed?  Called before ClosePanel() when the close
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // button is pressed to give beforeunload handlers a chance to cancel.
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    virtual bool CanClosePanel() = 0;
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Close the panel. Called when a close button is pressed.
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void ClosePanel() = 0;
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Activate the panel. Called when maximized.
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void ActivatePanel() = 0;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PanelController(Delegate* delegate_window,
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  GtkWindow* window);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~PanelController() {}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initializes the panel controller with the initial state of the focus and
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the window bounds.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Init(bool initial_focus, const gfx::Rect& init_bounds, XID creator_xid,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            WmIpcPanelUserResizeType resize_type);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool TitleMousePressed(const views::MouseEvent& event);
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void TitleMouseReleased(const views::MouseEvent& event);
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void TitleMouseCaptureLost();
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool TitleMouseDragged(const views::MouseEvent& event);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool PanelClientEvent(GdkEventClient* event);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnFocusIn();
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnFocusOut();
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateTitleBar();
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void SetUrgent(bool urgent);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Close();
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetState(State state);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool urgent() { return urgent_; }
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  class TitleContentView : public views::View,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           public views::ButtonListener {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   public:
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit TitleContentView(PanelController* panelController);
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    virtual ~TitleContentView();
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Overridden from View:
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void Layout() OVERRIDE;
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual void OnMouseCaptureLost() OVERRIDE;
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE;
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void OnFocusIn();
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void OnFocusOut();
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    void OnClose();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::ImageView* title_icon() { return title_icon_; }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::Label* title_label() { return title_label_; }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::ImageButton* close_button() { return close_button_; }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // ButtonListener methods.
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    virtual void ButtonPressed(views::Button* sender,
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               const views::Event& event) OVERRIDE;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch   private:
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::ImageView* title_icon_;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::Label* title_label_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::ImageButton* close_button_;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PanelController* panel_controller_;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DISALLOW_COPY_AND_ASSIGN(TitleContentView);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called from TitleContentView's ButtonPressed handler.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnCloseButtonPressed();
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Dispatches client events to PanelController instances
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static bool OnPanelClientEvent(
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GtkWidget* widget,
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GdkEventClient* event,
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PanelController* panel_controller);
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Panel's delegate.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Delegate* delegate_;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gtk object for content.
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWindow* panel_;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // X id for content.
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  XID panel_xid_;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Views object representing title.
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::Widget* title_window_;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gtk object representing title.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* title_;
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // X id representing title.
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  XID title_xid_;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Views object, holds title and close button.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TitleContentView* title_content_;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Is the panel expanded or collapsed?
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool expanded_;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Is the mouse button currently down?
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool mouse_down_;
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cursor's absolute position when the mouse button was pressed.
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int mouse_down_abs_x_;
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int mouse_down_abs_y_;
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cursor's offset from the upper-left corner of the titlebar when the
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // mouse button was pressed.
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int mouse_down_offset_x_;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int mouse_down_offset_y_;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Is the titlebar currently being dragged?  That is, has the cursor
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // moved more than kDragThreshold away from its starting position?
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool dragging_;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GTK client event handler id.
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int client_event_handler_id_;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Focused state.
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool focused_;
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Urgent (highlight) state.
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool urgent_;
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Timestamp to prevent setting urgent immediately after clearing it.
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::TimeTicks urgent_cleared_time_;
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(PanelController);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace chromeos
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_CHROMEOS_FRAME_PANEL_CONTROLLER_H_
184