8bfb16ef229df1acd525f844d6c0883b95bf434c
[platform/framework/web/crosswalk.git] / src / ash / wm / window_state.h
1 // Copyright 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 ASH_WM_WINDOW_STATE_H_
6 #define ASH_WM_WINDOW_STATE_H_
7
8 #include "ash/ash_export.h"
9 #include "ash/wm/drag_details.h"
10 #include "ash/wm/wm_types.h"
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "ui/aura/window_observer.h"
16 #include "ui/base/ui_base_types.h"
17
18 namespace aura {
19 class Window;
20 }
21
22 namespace gfx {
23 class Rect;
24 }
25
26 namespace ash {
27 namespace internal {
28 class WorkspaceLayoutManager;
29 class MaximizeModeWindowState;
30 }
31
32 namespace wm {
33 class WindowStateDelegate;
34 class WindowStateObserver;
35 class WMEvent;
36
37 // WindowState manages and defines ash specific window state and
38 // behavior. Ash specific per-window state (such as ones that controls
39 // window manager behavior) and ash specific window behavior (such as
40 // maximize, minimize, snap sizing etc) should be added here instead
41 // of defining separate functions (like |MaximizeWindow(aura::Window*
42 // window)|) or using aura Window property.
43 // The WindowState gets created when first accessed by
44 // |wm::GetWindowState|, and deleted when the window is deleted.
45 // Prefer using this class instead of passing aura::Window* around in
46 // ash code as this is often what you need to interact with, and
47 // accessing the window using |window()| is cheap.
48 class ASH_EXPORT WindowState : public aura::WindowObserver {
49  public:
50
51   // A subclass of State class represents one of the window's states
52   // that corresponds to WindowStateType in Ash environment, e.g.
53   // maximized, minimized or side snapped, as subclass.
54   // Each subclass defines its own behavior and transition for each WMEvent.
55   class State {
56    public:
57     State() {}
58     virtual ~State() {}
59
60     // Update WindowState based on |event|.
61     virtual void OnWMEvent(WindowState* window_state, const WMEvent* event) = 0;
62
63     virtual WindowStateType GetType() const = 0;
64
65     // Gets called when the state object became active and the managed window
66     // needs to be adjusted to the State's requirement.
67     // The passed |previous_state| may be used to properly implement state
68     // transitions such as bound animations from the previous state.
69     // Note: This only gets called when the state object gets changed.
70     virtual void AttachState(WindowState* window_state,
71                              State* previous_state) = 0;
72
73     // Gets called before the state objects gets deactivated / detached from the
74     // window, so that it can save the various states it is interested in.
75     // Note: This only gets called when the state object gets changed.
76     virtual void DetachState(WindowState* window_state) = 0;
77
78    private:
79     DISALLOW_COPY_AND_ASSIGN(State);
80   };
81
82   explicit WindowState(aura::Window* window);
83   virtual ~WindowState();
84
85   aura::Window* window() { return window_; }
86   const aura::Window* window() const { return window_; }
87
88   bool HasDelegate() const;
89   void SetDelegate(scoped_ptr<WindowStateDelegate> delegate);
90
91   // Returns the window's current ash state type.
92   // Refer to WindowStateType definition in wm_types.h as for why Ash
93   // has its own state type.
94   WindowStateType GetStateType() const;
95
96   // Predicates to check window state.
97   bool IsMinimized() const;
98   bool IsMaximized() const;
99   bool IsFullscreen() const;
100   bool IsMaximizedOrFullscreen() const;
101   bool IsSnapped() const;
102
103   // True if the window's state type is WINDOW_STATE_TYPE_NORMAL or
104   // WINDOW_STATE_TYPE_DEFAULT.
105   bool IsNormalStateType() const;
106
107   bool IsNormalOrSnapped() const;
108
109   bool IsActive() const;
110   bool IsDocked() const;
111
112   // Checks if the window can change its state accordingly.
113   bool CanMaximize() const;
114   bool CanMinimize() const;
115   bool CanResize() const;
116   bool CanSnap() const;
117   bool CanActivate() const;
118
119   // Returns true if the window has restore bounds.
120   bool HasRestoreBounds() const;
121
122   // These methods use aura::WindowProperty to change the window's state
123   // instead of using WMEvent directly. This is to use the same mechanism as
124   // what views::Widget is using.
125   void Maximize();
126   void Minimize();
127   void Unminimize();
128
129   void Activate();
130   void Deactivate();
131
132   // Set the window state to normal.
133   // TODO(oshima): Change to use RESTORE event.
134   void Restore();
135
136   // Invoked when a WMevent occurs, which drives the internal
137   // state machine.
138   void OnWMEvent(const WMEvent* event);
139
140   // TODO(oshima): Try hiding these methods and making them accessible only to
141   // state impl. State changes should happen through events (as much
142   // as possible).
143
144   // Saves the current bounds to be used as a restore bounds.
145   void SaveCurrentBoundsForRestore();
146
147   // Same as |GetRestoreBoundsInScreen| except that it returns the
148   // bounds in the parent's coordinates.
149   gfx::Rect GetRestoreBoundsInParent() const;
150
151   // Returns the restore bounds property on the window in the virtual screen
152   // coordinates. The bounds can be NULL if the bounds property does not
153   // exist for the window. The window owns the bounds object.
154   gfx::Rect GetRestoreBoundsInScreen() const;
155
156   // Same as |SetRestoreBoundsInScreen| except that the bounds is in the
157   // parent's coordinates.
158   void SetRestoreBoundsInParent(const gfx::Rect& bounds_in_parent);
159
160   // Sets the restore bounds property on the window in the virtual screen
161   // coordinates.  Deletes existing bounds value if exists.
162   void SetRestoreBoundsInScreen(const gfx::Rect& bounds_in_screen);
163
164   // Deletes and clears the restore bounds property on the window.
165   void ClearRestoreBounds();
166
167   // Replace the State object of a window with a state handler which can
168   // implement a new window manager type. The passed object will be owned
169   // by this object and the returned object will be owned by the caller.
170   scoped_ptr<State> SetStateObject(scoped_ptr<State> new_state);
171
172   // True if the window should be unminimized to the restore bounds, as
173   // opposed to the window's current bounds. |unminimized_to_restore_bounds_| is
174   // reset to the default value after the window is unminimized.
175   bool unminimize_to_restore_bounds() const {
176     return unminimize_to_restore_bounds_;
177   }
178   void set_unminimize_to_restore_bounds(bool value) {
179     unminimize_to_restore_bounds_ = value;
180   }
181
182   // Gets/sets whether the shelf should be hidden when this window is
183   // fullscreen.
184   bool hide_shelf_when_fullscreen() const {
185     return hide_shelf_when_fullscreen_;
186   }
187
188   void set_hide_shelf_when_fullscreen(bool value) {
189     hide_shelf_when_fullscreen_ = value;
190   }
191
192   // If the minimum visibilty is true, ash will try to keep a
193   // minimum amount of the window is always visible on the work area
194   // when shown.
195   // TODO(oshima): Consolidate this and window_position_managed
196   // into single parameter to control the window placement.
197   bool minimum_visibility() const {
198     return minimum_visibility_;
199   }
200   void set_minimum_visibility(bool minimum_visibility) {
201     minimum_visibility_ = minimum_visibility;
202   }
203
204   // Specifies if the window can be dragged by the user via the caption or not.
205   bool can_be_dragged() const {
206     return can_be_dragged_;
207   }
208   void set_can_be_dragged(bool can_be_dragged) {
209     can_be_dragged_ = can_be_dragged;
210   }
211
212   // Gets/Sets the bounds of the window before it was moved by the auto window
213   // management. As long as it was not auto-managed, it will return NULL.
214   const gfx::Rect* pre_auto_manage_window_bounds() const {
215     return pre_auto_manage_window_bounds_.get();
216   }
217   void SetPreAutoManageWindowBounds(const gfx::Rect& bounds);
218
219   // Layout related properties
220
221   void AddObserver(WindowStateObserver* observer);
222   void RemoveObserver(WindowStateObserver* observer);
223
224   // Whether the window is being dragged.
225   bool is_dragged() const {
226     return drag_details_;
227   }
228
229   // Whether or not the window's position can be managed by the
230   // auto management logic.
231   bool window_position_managed() const { return window_position_managed_; }
232   void set_window_position_managed(bool window_position_managed) {
233     window_position_managed_ = window_position_managed;
234   }
235
236   // Whether or not the window's position or size was changed by a user.
237   bool bounds_changed_by_user() const { return bounds_changed_by_user_; }
238   void set_bounds_changed_by_user(bool bounds_changed_by_user) {
239     bounds_changed_by_user_ = bounds_changed_by_user;
240   }
241
242   // True if this window is an attached panel.
243   bool panel_attached() const {
244     return panel_attached_;
245   }
246   void set_panel_attached(bool panel_attached) {
247     panel_attached_ = panel_attached;
248   }
249
250   // True if the window is ignored by the shelf layout manager for
251   // purposes of darkening the shelf.
252   bool ignored_by_shelf() const { return ignored_by_shelf_; }
253   void set_ignored_by_shelf(bool ignored_by_shelf) {
254     ignored_by_shelf_ = ignored_by_shelf;
255   }
256
257   // True if the window should be offered a chance to consume special system
258   // keys such as brightness, volume, etc. that are usually handled by the
259   // shell.
260   bool can_consume_system_keys() const { return can_consume_system_keys_; }
261   void set_can_consume_system_keys(bool can_consume_system_keys) {
262     can_consume_system_keys_ = can_consume_system_keys;
263   }
264
265   // True if this window has requested that the top-row keys (back, forward,
266   // brightness, volume) should be treated as function keys.
267   bool top_row_keys_are_function_keys() const {
268     return top_row_keys_are_function_keys_;
269   }
270   void set_top_row_keys_are_function_keys(bool value) {
271     top_row_keys_are_function_keys_ = value;
272   }
273
274   // Creates and takes ownership of a pointer to DragDetails when resizing is
275   // active. This should be done before a resizer gets created.
276   void CreateDragDetails(aura::Window* window,
277                          const gfx::Point& point_in_parent,
278                          int window_component,
279                          aura::client::WindowMoveSource source);
280
281   // Deletes and clears a pointer to DragDetails. This should be done when the
282   // resizer gets destroyed.
283   void DeleteDragDetails();
284
285   // Sets the currently stored restore bounds and clears the restore bounds.
286   void SetAndClearRestoreBounds();
287
288   // Returns a pointer to DragDetails during drag operations.
289   const DragDetails* drag_details() const { return drag_details_.get(); }
290   DragDetails* drag_details() { return drag_details_.get(); }
291
292   // aura::WindowObserver overrides:
293   virtual void OnWindowPropertyChanged(aura::Window* window,
294                                        const void* key,
295                                        intptr_t old) OVERRIDE;
296
297  private:
298   friend class DefaultState;
299   friend class ash::internal::MaximizeModeWindowState;
300   FRIEND_TEST_ALL_PREFIXES(WindowAnimationsTest, CrossFadeToBounds);
301
302   WindowStateDelegate* delegate() { return delegate_.get(); }
303
304   // Returns the window's current show state.
305   ui::WindowShowState GetShowState() const;
306
307   // Sets the window's bounds in screen coordinates.
308   void SetBoundsInScreen(const gfx::Rect& bounds_in_screen);
309
310   // Adjusts the |bounds| so that they are flush with the edge of the
311   // workspace if the window represented by |window_state| is side snapped.
312   void AdjustSnappedBounds(gfx::Rect* bounds);
313
314   // Updates the window show state according to the current window state type.
315   // Note that this does not update the window bounds.
316   void UpdateWindowShowStateFromStateType();
317
318   void NotifyPreStateTypeChange(WindowStateType old_window_state_type);
319   void NotifyPostStateTypeChange(WindowStateType old_window_state_type);
320
321   // Sets |bounds| as is.
322   void SetBoundsDirect(const gfx::Rect& bounds);
323
324   // Sets the window's |bounds| with constraint where the size of the
325   // new bounds will not exceeds the size of the work area.
326   void SetBoundsConstrained(const gfx::Rect& bounds);
327
328   // Sets the wndow's |bounds| and transitions to the new bounds with
329   // a scale animation.
330   void SetBoundsDirectAnimated(const gfx::Rect& bounds);
331
332   // Sets the window's |bounds| and transition to the new bounds with
333   // a cross fade animation.
334   void SetBoundsDirectCrossFade(const gfx::Rect& bounds);
335
336   // The owner of this window settings.
337   aura::Window* window_;
338   scoped_ptr<WindowStateDelegate> delegate_;
339
340   bool window_position_managed_;
341   bool bounds_changed_by_user_;
342   bool panel_attached_;
343   bool ignored_by_shelf_;
344   bool can_consume_system_keys_;
345   bool top_row_keys_are_function_keys_;
346   scoped_ptr<DragDetails> drag_details_;
347
348   bool unminimize_to_restore_bounds_;
349   bool hide_shelf_when_fullscreen_;
350   bool minimum_visibility_;
351   bool can_be_dragged_;
352
353   // A property to remember the window position which was set before the
354   // auto window position manager changed the window bounds, so that it can get
355   // restored when only this one window gets shown.
356   scoped_ptr<gfx::Rect> pre_auto_manage_window_bounds_;
357
358   ObserverList<WindowStateObserver> observer_list_;
359
360   // True to ignore a property change event to avoid reentrance in
361   // UpdateWindowStateType()
362   bool ignore_property_change_;
363
364   scoped_ptr<State> current_state_;
365
366   DISALLOW_COPY_AND_ASSIGN(WindowState);
367 };
368
369 // Returns the WindowState for active window. Returns |NULL|
370 // if there is no active window.
371 ASH_EXPORT WindowState* GetActiveWindowState();
372
373 // Returns the WindowState for |window|. Creates WindowState
374 // if it didn't exist. The settings object is owned by |window|.
375 ASH_EXPORT WindowState* GetWindowState(aura::Window* window);
376
377 // const version of GetWindowState.
378 ASH_EXPORT const WindowState*
379 GetWindowState(const aura::Window* window);
380
381 }  // namespace wm
382 }  // namespace ash
383
384 #endif  // ASH_WM_WINDOW_STATE_H_