text: // Copyright (c) 2009 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef VIEWS_WIDGET_ROOT_VIEW_H_
  #define VIEWS_WIDGET_ROOT_VIEW_H_
  
  #include <string>
  
  #include "base/ref_counted.h"
  #include "views/focus/focus_manager.h"
  #include "views/view.h"
  
  #if defined(OS_LINUX)
  typedef struct _GdkEventExpose GdkEventExpose;
  #endif
  
  namespace views {
  
  class PaintTask;
  class Widget;
  
  /////////////////////////////////////////////////////////////////////////////
  //
  // RootView class
  //
  //   The RootView is the root of a View hierarchy. A RootView is always the
  //   first and only child of a Widget.
  //
  //   The RootView manages the View hierarchy's interface with the Widget
  //   and also maintains the current invalid rect - the region that needs
  //   repainting.
  //
  /////////////////////////////////////////////////////////////////////////////
  class RootView : public View,
                   public FocusTraversable {
   public:
    static const char kViewClassName[];
  
    explicit RootView(Widget* widget);
  
    virtual ~RootView();
  
    // Sets the "contents view" of the RootView. This is the single child view
    // that is responsible for laying out the contents of the widget.
    void SetContentsView(View* contents_view);
  
    // Layout and Painting functions
  
    // Overridden from View to implement paint scheduling.
    virtual void SchedulePaint(const gfx::Rect& r, bool urgent);
  
    // Convenience to schedule the whole view
    virtual void SchedulePaint();
  
    // Convenience to schedule a paint given some ints
    virtual void SchedulePaint(int x, int y, int w, int h);
  
    // Paint this RootView and its child Views.
    virtual void ProcessPaint(gfx::Canvas* canvas);
  
    // If the invalid rect is non-empty and there is a pending paint the RootView
    // is painted immediately. This is internally invoked as the result of
    // invoking SchedulePaint.
    virtual void PaintNow();
  
    // Whether or not this View needs repainting. If |urgent| is true, this method
    // returns whether this root view needs to paint as soon as possible.
    virtual bool NeedsPainting(bool urgent);
  
    // Invoked by the Widget to discover what rectangle should be painted.
    const gfx::Rect& GetScheduledPaintRect();
  
    // Returns the region scheduled to paint clipped to the RootViews bounds.
    gfx::Rect GetScheduledPaintRectConstrainedToSize();
  
    // Tree functions
  
    // Get the Widget that hosts this View.
    virtual Widget* GetWidget() const;
  
    // Public API for broadcasting theme change notifications to this View
    // hierarchy.
    virtual void ThemeChanged();
  
    // The following event methods are overridden to propagate event to the
    // control tree
    virtual bool OnMousePressed(const MouseEvent& e);
    virtual bool OnMouseDragged(const MouseEvent& e);
    virtual void OnMouseReleased(const MouseEvent& e, bool canceled);
    virtual void OnMouseMoved(const MouseEvent& e);
    virtual void SetMouseHandler(View* new_mouse_handler);
  
    // Invoked By the Widget if the mouse drag is interrupted by
    // the system. Invokes OnMouseReleased with a value of true for canceled.
    void ProcessMouseDragCanceled();
  
    // Invoked by the Widget instance when the mouse moves outside of the Widget
    // bounds.
    virtual void ProcessOnMouseExited();
  
    // Make the provided view focused. Also make sure that our Widget is focused.
    void FocusView(View* view);
  
    // Check whether the provided view is in the focus path. The focus path is the
    // path between the focused view (included) to the root view.
    bool IsInFocusPath(View* view);
  
    // Returns the View in this RootView hierarchy that has the focus, or NULL if
    // no View currently has the focus.
    View* GetFocusedView();
  
    // Process a key event. Send the event to the focused view and up the focus
    // path, and finally to the default keyboard handler, until someone consumes
    // it.  Returns whether anyone consumed the event.
    bool ProcessKeyEvent(const KeyEvent& event);
  
    // Set the default keyboard handler. The default keyboard handler is
    // a view that will get an opportunity to process key events when all
    // views in the focus path did not process an event.
    //
    // Note: this is a single view at this point. We may want to make
    // this a list if needed.
    void SetDefaultKeyboardHandler(View* v);
  
    // Set whether this root view should focus the corresponding hwnd
    // when an unprocessed mouse event occurs.
    void SetFocusOnMousePressed(bool f);
  
    // Process a mousewheel event. Return true if the event was processed
    // and false otherwise.
    // MouseWheel events are sent on the focus path.
    virtual bool ProcessMouseWheelEvent(const MouseWheelEvent& e);
  
    // Overridden to handle special root view case.
    virtual bool IsVisibleInRootView() const;
  
    // FocusTraversable implementation.
    virtual View* FindNextFocusableView(View* starting_view,
                                        bool reverse,
                                        Direction direction,
                                        bool check_starting_view,
                                        FocusTraversable** focus_traversable,
                                        View** focus_traversable_view);
    virtual FocusTraversable* GetFocusTraversableParent();
    virtual View* GetFocusTraversableParentView();
  
    // Used to set the FocusTraversable parent after the view has been created
    // (typically when the hierarchy changes and this RootView is added/removed).
    virtual void SetFocusTraversableParent(FocusTraversable* focus_traversable);
  
    // Used to set the View parent after the view has been created.
    virtual void SetFocusTraversableParentView(View* view);
  
    // Called when parent of the host changed.
    void NotifyNativeViewHierarchyChanged(bool attached,
                                          gfx::NativeView native_view);
  
    // Returns the name of this class: views/RootView
    virtual std::string GetClassName() const;
  
    // Clears the region that is schedule to be painted. You nearly never need
    // to invoke this. This is primarily intended for Widgets.
    void ClearPaintRect();
  
  #if defined(OS_WIN)
    // Invoked from the Widget to service a WM_PAINT call.
    void OnPaint(HWND hwnd);
  #elif defined(OS_LINUX)
    void OnPaint(GdkEventExpose* event);
  #endif
  
    // Starts a drag operation for the specified view. This blocks until done.
    // If the view has not been deleted during the drag, OnDragDone is invoked
    // on the view.
    // NOTE: |view| may be null.
    void StartDragForViewFromMouseEvent(View* view,
                                        const OSExchangeData& data,
                                        int operation);
  
    // Accessibility accessors/mutators, overridden from View.
    virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
    virtual bool GetAccessibleName(std::wstring* name);
    virtual void SetAccessibleName(const std::wstring& name);
  
   protected:
  
    // Overridden to properly reset our event propagation member
    // variables when a child is removed
    virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child);
  
  #ifndef NDEBUG
    virtual bool IsProcessingPaint() const { return is_processing_paint_; }
  #endif
  
   private:
    friend class View;
    friend class PaintTask;
  
    RootView();
  
    // Convert a point to our current mouse handler. Returns false if the
    // mouse handler is not connected to a Widget. In that case, the
    // conversion cannot take place and *p is unchanged
    bool ConvertPointToMouseHandler(const gfx::Point& l, gfx::Point *p);
  
    // Update the cursor given a mouse event. This is called by non mouse_move
    // event handlers to honor the cursor desired by views located under the
    // cursor during drag operations.
    void UpdateCursor(const MouseEvent& e);
  
    // Notification that size and/or position of a view has changed. This
    // notifies the appropriate views.
    void ViewBoundsChanged(View* view, bool size_changed, bool position_changed);
  
    // Registers a view for notification when the visible bounds relative to the
    // root of a view changes.
    void RegisterViewForVisibleBoundsNotification(View* view);
    void UnregisterViewForVisibleBoundsNotification(View* view);
  
    // Returns the next focusable view or view containing a FocusTraversable (NULL
    // if none was found), starting at the starting_view.
    // check_starting_view, can_go_up and can_go_down controls the traversal of
    // the views hierarchy.
    // skip_group_id specifies a group_id, -1 means no group. All views from a
    // group are traversed in one pass.
    View* FindNextFocusableViewImpl(View* starting_view,
                                    bool check_starting_view,
                                    bool can_go_up,
                                    bool can_go_down,
                                    int skip_group_id,
                                    FocusTraversable** focus_traversable,
                                    View** focus_traversable_view);
  
    // Same as FindNextFocusableViewImpl but returns the previous focusable view.
    View* FindPreviousFocusableViewImpl(View* starting_view,
                                        bool check_starting_view,
                                        bool can_go_up,
                                        bool can_go_down,
                                        int skip_group_id,
                                        FocusTraversable** focus_traversable,
                                        View** focus_traversable_view);
  
    // Convenience method that returns true if a view is focusable and does not
    // belong to the specified group.
    bool IsViewFocusableCandidate(View* v, int skip_group_id);
  
    // Returns the view selected for the group of the selected view. If the view
    // does not belong to a group or if no view is selected in the group, the
    // specified view is returned.
    static View* FindSelectedViewForGroup(View* view);
  
    // Updates the last_mouse_* fields from e.
    void SetMouseLocationAndFlags(const MouseEvent& e);
  
    // If a view is dragging, this returns it. Otherwise returns NULL.
    View* GetDragView();
  
    // Sets the current cursor, or resets it to the last one if NULL is provided.
    void SetActiveCursor(gfx::NativeCursor cursor);
  
    // The view currently handing down - drag - up
    View* mouse_pressed_handler_;
  
    // The view currently handling enter / exit
    View* mouse_move_handler_;
  
    // The last view to handle a mouse click, so that we can determine if
    // a double-click lands on the same view as its single-click part.
    View* last_click_handler_;
  
    // The host Widget
    Widget* widget_;
  
    // The rectangle that should be painted
    gfx::Rect invalid_rect_;
  
    // Whether the current invalid rect should be painted urgently.
    bool invalid_rect_urgent_;
  
    // The task that we are using to trigger some non urgent painting or NULL
    // if no painting has been scheduled yet.
    PaintTask* pending_paint_task_;
  
    // Indicate if, when the pending_paint_task_ is run, actual painting is still
    // required.
    bool paint_task_needed_;
  
    // true if mouse_handler_ has been explicitly set
    bool explicit_mouse_handler_;
  
    // Previous cursor
    gfx::NativeCursor previous_cursor_;
  
    // Default keyboard handler
    View* default_keyboard_handler_;
  
    // Whether this root view should make our hwnd focused
    // when an unprocessed mouse press event occurs
    bool focus_on_mouse_pressed_;
  
    // Flag used to ignore focus events when we focus the native window associated
    // with a view.
    bool ignore_set_focus_calls_;
  
    // Whether this root view belongs to the current active window.
    // bool activated_;
  
    // Last position/flag of a mouse press/drag. Used if capture stops and we need
    // to synthesize a release.
    int last_mouse_event_flags_;
    int last_mouse_event_x_;
    int last_mouse_event_y_;
  
    // The parent FocusTraversable, used for focus traversal.
    FocusTraversable* focus_traversable_parent_;
  
    // The View that contains this RootView. This is used when we have RootView
    // wrapped inside native components, and is used for the focus traversal.
    View* focus_traversable_parent_view_;
  
    // Storage of strings needed for accessibility.
    std::wstring accessible_name_;
  
    // Tracks drag state for a view.
    View::DragInfo drag_info;
  
    // Valid for the lifetime of StartDragForViewFromMouseEvent, indicates the
    // view the drag started from.
    View* drag_view_;
  
  #ifndef NDEBUG
    // True if we're currently processing paint.
    bool is_processing_paint_;
  #endif
  
    DISALLOW_COPY_AND_ASSIGN(RootView);
  };
  
  }  // namespace views
  
  #endif  // VIEWS_WIDGET_ROOT_VIEW_H_
  