1/*
2 * Copyright (C) 2004, 2005, 2006 Apple Inc.  All rights reserved.
3 * Copyright (C) 2008 Collabora Ltd.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef Widget_h
28#define Widget_h
29
30#if PLATFORM(IOS)
31#ifndef NSView
32#define NSView WAKView
33#endif
34#endif
35
36#include "IntRect.h"
37#include "PlatformScreen.h"
38#include <wtf/Forward.h>
39#include <wtf/RefCounted.h>
40
41#if PLATFORM(COCOA)
42#include <wtf/RetainPtr.h>
43#endif
44
45#if PLATFORM(COCOA)
46OBJC_CLASS NSView;
47OBJC_CLASS NSWindow;
48typedef NSView *PlatformWidget;
49#endif
50
51#if PLATFORM(WIN)
52typedef struct HWND__* HWND;
53typedef HWND PlatformWidget;
54#endif
55
56#if PLATFORM(GTK)
57typedef struct _GtkWidget GtkWidget;
58typedef struct _GtkContainer GtkContainer;
59typedef GtkWidget* PlatformWidget;
60#endif
61
62#if PLATFORM(EFL)
63typedef Evas_Object* PlatformWidget;
64#endif
65
66typedef PlatformWidget PlatformPageClient;
67
68namespace WebCore {
69
70class Cursor;
71class Event;
72class Font;
73class GraphicsContext;
74class PlatformMouseEvent;
75class ScrollView;
76
77enum WidgetNotification { WillPaintFlattened, DidPaintFlattened };
78
79// The Widget class serves as a base class for three kinds of objects:
80// (1) Scrollable areas (ScrollView)
81// (2) Scrollbars (Scrollbar)
82// (3) Plugins (PluginView)
83//
84// A widget may or may not be backed by a platform-specific object (e.g., HWND on Windows, NSView on Mac, QWidget on Qt).
85//
86// Widgets are connected in a hierarchy, with the restriction that plugins and scrollbars are always leaves of the
87// tree.  Only ScrollViews can have children (and therefore the Widget class has no concept of children).
88//
89// The rules right now for which widgets get platform-specific objects are as follows:
90// ScrollView - Mac
91// Scrollbar - Mac, Gtk
92// Plugin - Mac, Windows (windowed only), Qt (windowed only, widget is an HWND on windows), Gtk (windowed only)
93//
94class Widget : public RefCounted<Widget> {
95public:
96    explicit Widget(PlatformWidget = 0);
97    virtual ~Widget();
98
99    PlatformWidget platformWidget() const;
100    void setPlatformWidget(PlatformWidget);
101
102    int x() const { return frameRect().x(); }
103    int y() const { return frameRect().y(); }
104    int width() const { return frameRect().width(); }
105    int height() const { return frameRect().height(); }
106    IntSize size() const { return frameRect().size(); }
107    IntPoint location() const { return frameRect().location(); }
108
109    virtual void setFrameRect(const IntRect&);
110    IntRect frameRect() const;
111    IntRect boundsRect() const { return IntRect(0, 0, width(),  height()); }
112
113    void resize(int w, int h) { setFrameRect(IntRect(x(), y(), w, h)); }
114    void resize(const IntSize& s) { setFrameRect(IntRect(location(), s)); }
115    void move(int x, int y) { setFrameRect(IntRect(x, y, width(), height())); }
116    void move(const IntPoint& p) { setFrameRect(IntRect(p, size())); }
117
118    virtual void paint(GraphicsContext*, const IntRect&);
119    void invalidate() { invalidateRect(boundsRect()); }
120    virtual void invalidateRect(const IntRect&) = 0;
121
122    virtual void setFocus(bool);
123
124    void setCursor(const Cursor&);
125
126    virtual void show();
127    virtual void hide();
128    bool isSelfVisible() const { return m_selfVisible; } // Whether or not we have been explicitly marked as visible or not.
129    bool isParentVisible() const { return m_parentVisible; } // Whether or not our parent is visible.
130    bool isVisible() const { return m_selfVisible && m_parentVisible; } // Whether or not we are actually visible.
131    virtual void setParentVisible(bool visible) { m_parentVisible = visible; }
132    void setSelfVisible(bool v) { m_selfVisible = v; }
133
134    void setIsSelected(bool);
135
136    virtual bool isFrameView() const { return false; }
137    virtual bool isPluginView() const { return false; }
138    // FIXME: The Mac plug-in code should inherit from PluginView. When this happens PluginViewBase and PluginView can become one class.
139    virtual bool isPluginViewBase() const { return false; }
140    virtual bool isScrollbar() const { return false; }
141    virtual bool isScrollView() const { return false; }
142
143    void removeFromParent();
144    virtual void setParent(ScrollView* view);
145    ScrollView* parent() const { return m_parent; }
146    ScrollView* root() const;
147
148    virtual void handleEvent(Event*) { }
149
150    virtual void notifyWidget(WidgetNotification) { }
151
152    IntRect convertToRootView(const IntRect&) const;
153    IntRect convertFromRootView(const IntRect&) const;
154
155    IntPoint convertToRootView(const IntPoint&) const;
156    IntPoint convertFromRootView(const IntPoint&) const;
157
158    // It is important for cross-platform code to realize that Mac has flipped coordinates.  Therefore any code
159    // that tries to convert the location of a rect using the point-based convertFromContainingWindow will end
160    // up with an inaccurate rect.  Always make sure to use the rect-based convertFromContainingWindow method
161    // when converting window rects.
162    IntRect convertToContainingWindow(const IntRect&) const;
163    IntRect convertFromContainingWindow(const IntRect&) const;
164
165    IntPoint convertToContainingWindow(const IntPoint&) const;
166    IntPoint convertFromContainingWindow(const IntPoint&) const;
167
168    virtual void frameRectsChanged() { }
169
170    // Notifies this widget that its clip rect changed.
171    virtual void clipRectChanged() { }
172
173    // Whether transforms affect the frame rect. FIXME: We get rid of this and have
174    // the frame rects be the same no matter what transforms are applied.
175    virtual bool transformsAffectFrameRect() { return true; }
176
177#if PLATFORM(COCOA)
178    NSView* getOuterView() const;
179
180    void removeFromSuperview();
181#endif
182#if PLATFORM(IOS)
183    void addToSuperview(NSView*);
184#endif
185
186    // Virtual methods to convert points to/from the containing ScrollView
187    virtual IntRect convertToContainingView(const IntRect&) const;
188    virtual IntRect convertFromContainingView(const IntRect&) const;
189    virtual IntPoint convertToContainingView(const IntPoint&) const;
190    virtual IntPoint convertFromContainingView(const IntPoint&) const;
191
192private:
193    void init(PlatformWidget); // Must be called by all Widget constructors to initialize cross-platform data.
194
195    void releasePlatformWidget();
196    void retainPlatformWidget();
197
198    // These methods are used to convert from the root widget to the containing window,
199    // which has behavior that may differ between platforms (e.g. Mac uses flipped window coordinates).
200    static IntRect convertFromRootToContainingWindow(const Widget* rootWidget, const IntRect&);
201    static IntRect convertFromContainingWindowToRoot(const Widget* rootWidget, const IntRect&);
202
203    static IntPoint convertFromRootToContainingWindow(const Widget* rootWidget, const IntPoint&);
204    static IntPoint convertFromContainingWindowToRoot(const Widget* rootWidget, const IntPoint&);
205
206private:
207    ScrollView* m_parent;
208#if !PLATFORM(COCOA)
209    PlatformWidget m_widget;
210#else
211    RetainPtr<NSView> m_widget;
212#endif
213    bool m_selfVisible;
214    bool m_parentVisible;
215
216    IntRect m_frame; // Not used when a native widget exists.
217};
218
219#define WIDGET_TYPE_CASTS(ToValueTypeName, predicate) \
220    TYPE_CASTS_BASE(ToValueTypeName, Widget, object, object->predicate, object.predicate)
221
222#if !PLATFORM(COCOA)
223
224inline PlatformWidget Widget::platformWidget() const
225{
226    return m_widget;
227}
228
229inline void Widget::setPlatformWidget(PlatformWidget widget)
230{
231    if (widget != m_widget) {
232        releasePlatformWidget();
233        m_widget = widget;
234        retainPlatformWidget();
235    }
236}
237
238#endif
239
240#if !PLATFORM(GTK)
241
242inline void Widget::releasePlatformWidget()
243{
244}
245
246inline void Widget::retainPlatformWidget()
247{
248}
249
250#endif
251
252} // namespace WebCore
253
254#endif // Widget_h
255