Back to index

lightning-sunbird  0.9+nobinonly
nsWidget.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsWidget_h__
00039 #define nsWidget_h__
00040 
00041 #include "nsBaseWidget.h"
00042 #include "nsWeakReference.h"
00043 #include "nsIKBStateControl.h"
00044 #include "nsIRegion.h"
00045 #include "nsIRollupListener.h"
00046 
00047 class nsILookAndFeel;
00048 class nsIAppShell;
00049 class nsIToolkit;
00050 
00051 #include <gtk/gtk.h>
00052 
00053 #include <gdk/gdkprivate.h>
00054 
00055 #include "gtkmozbox.h"
00056 #include "nsITimer.h"
00057 
00058 #define NSRECT_TO_GDKRECT(ns,gdk) \
00059   PR_BEGIN_MACRO \
00060   gdk.x = ns.x; \
00061   gdk.y = ns.y; \
00062   gdk.width = ns.width; \
00063   gdk.height = ns.height; \
00064   PR_END_MACRO
00065 
00066 #define NSCOLOR_TO_GDKCOLOR(n,g) \
00067   PR_BEGIN_MACRO \
00068   g.red = 256 * NS_GET_R(n); \
00069   g.green = 256 * NS_GET_G(n); \
00070   g.blue = 256 * NS_GET_B(n); \
00071   PR_END_MACRO
00072 
00073 
00078 class nsWidget : public nsBaseWidget, public nsIKBStateControl, public nsSupportsWeakReference
00079 {
00080 public:
00081   nsWidget();
00082   virtual ~nsWidget();
00083 
00084   NS_DECL_ISUPPORTS_INHERITED
00085 
00086   // nsIWidget
00087 
00088   NS_IMETHOD            Create(nsIWidget *aParent,
00089                                const nsRect &aRect,
00090                                EVENT_CALLBACK aHandleEventFunction,
00091                                nsIDeviceContext *aContext,
00092                                nsIAppShell *aAppShell = nsnull,
00093                                nsIToolkit *aToolkit = nsnull,
00094                                nsWidgetInitData *aInitData = nsnull);
00095   NS_IMETHOD            Create(nsNativeWidget aParent,
00096                                const nsRect &aRect,
00097                                EVENT_CALLBACK aHandleEventFunction,
00098                                nsIDeviceContext *aContext,
00099                                nsIAppShell *aAppShell = nsnull,
00100                                nsIToolkit *aToolkit = nsnull,
00101                                nsWidgetInitData *aInitData = nsnull);
00102 
00103   NS_IMETHOD Destroy(void);
00104   nsIWidget* GetParent(void);
00105   virtual void OnDestroy();
00106 
00107   NS_IMETHOD Show(PRBool state);
00108   NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
00109   NS_IMETHOD IsVisible(PRBool &aState);
00110 
00111   NS_IMETHOD ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY);
00112   NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
00113   NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint);
00114   NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth,
00115                     PRInt32 aHeight, PRBool aRepaint);
00116 
00117   NS_IMETHOD Enable(PRBool aState);
00118   NS_IMETHOD IsEnabled(PRBool *aState);
00119   NS_IMETHOD SetFocus(PRBool aRaise);
00120 
00121   virtual void LoseFocus(void);
00122 
00123   PRBool OnResize(nsSizeEvent *event);
00124   virtual PRBool OnResize(nsRect &aRect);
00125   virtual PRBool OnMove(PRInt32 aX, PRInt32 aY);
00126 
00127   NS_IMETHOD SetZIndex(PRInt32 aZIndex);
00128 
00129   nsIFontMetrics *GetFont(void);
00130   NS_IMETHOD SetFont(const nsFont &aFont);
00131 
00132   NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
00133 
00134   NS_IMETHOD SetCursor(nsCursor aCursor);
00135 
00136   NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
00137 
00138   void* GetNativeData(PRUint32 aDataType);
00139 
00140   NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect);
00141   NS_IMETHOD ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect);
00142 
00143   NS_IMETHOD BeginResizingChildren(void);
00144   NS_IMETHOD EndResizingChildren(void);
00145 
00146   NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight);
00147   NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight);
00148 
00149   // Use this to set the name of a widget for normal widgets.. not the same as the nsWindow version
00150   NS_IMETHOD SetTitle(const nsAString& aTitle);
00151 
00152 
00153   virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
00154 
00155   // the following are nsWindow specific, and just stubbed here
00156   NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) { return NS_ERROR_FAILURE; }
00157   NS_IMETHOD SetMenuBar(nsIMenuBar *aMenuBar) { return NS_ERROR_FAILURE; }
00158   NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
00159   // *could* be done on a widget, but that would be silly wouldn't it?
00160   NS_IMETHOD CaptureMouse(PRBool aCapture) { return NS_ERROR_FAILURE; }
00161 
00162   NS_IMETHOD GetWindowClass(char *aClass);
00163   NS_IMETHOD SetWindowClass(char *aClass);
00164 
00165   NS_IMETHOD Validate();
00166   NS_IMETHOD Invalidate(PRBool aIsSynchronous);
00167   NS_IMETHOD Invalidate(const nsRect &aRect, PRBool aIsSynchronous);
00168   NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
00169   NS_IMETHOD Update(void);
00170   NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
00171 
00172 
00173   // nsIKBStateControl
00174   NS_IMETHOD ResetInputState();
00175   NS_IMETHOD SetIMEOpenState(PRBool aState);
00176   NS_IMETHOD GetIMEOpenState(PRBool* aState);
00177   NS_IMETHOD CancelIMEComposition();
00178 
00179   void InitEvent(nsGUIEvent& event, nsPoint* aPoint = nsnull);
00180     
00181   // Utility functions
00182 
00183   PRBool     ConvertStatus(nsEventStatus aStatus);
00184   PRBool     DispatchMouseEvent(nsMouseEvent& aEvent);
00185   PRBool     DispatchStandardEvent(PRUint32 aMsg);
00186   PRBool     DispatchFocus(nsGUIEvent &aEvent);
00187 
00188   // are we a "top level" widget?
00189   PRBool     mIsToplevel;
00190 
00191   virtual void DispatchSetFocusEvent(void);
00192   virtual void DispatchLostFocusEvent(void);
00193   virtual void DispatchActivateEvent(void);
00194   virtual void DispatchDeactivateEvent(void);
00195 
00196 #ifdef DEBUG
00197   void IndentByDepth(FILE* out);
00198 #endif
00199 
00200   // Return the Gdk window used for rendering
00201   virtual GdkWindow * GetRenderWindow(GtkObject * aGtkWidget);
00202   // Return the Gdk window used for positioning, raising and lowering
00203   virtual GdkWindow* GetLayeringWindow();
00204 
00205 
00206   // get the toplevel window for this widget
00207   virtual GtkWindow *GetTopLevelWindow(void);
00208 
00209 
00210   PRBool   OnKey(nsKeyEvent &aEvent);
00211   PRBool   OnText(nsTextEvent &aEvent)       { return OnInput(aEvent); };
00212   PRBool   OnComposition(nsCompositionEvent &aEvent) { return OnInput(aEvent); };
00213   PRBool   OnInput(nsInputEvent &aEvent);
00214 
00215   // this will return the GtkWidget * that owns this object
00216   virtual GtkWidget *GetOwningWidget();
00217 
00218   // the event handling code needs to let us know the time of the last event
00219   static void SetLastEventTime(guint32 aTime);
00220   static void GetLastEventTime(guint32 *aTime);
00221 
00222   static void DropMotionTarget(void);
00223 
00224   // inform the widget code that we are about to do a drag - it must
00225   // release the sButtonMotionTarget if it is set.
00226   static void DragStarted(void) { DropMotionTarget(); };
00227 
00228   virtual void ThemeChanged();
00229 
00230 protected:
00231 
00232   virtual void InitCallbacks(char * aName = nsnull);
00233 
00234   NS_IMETHOD CreateNative(GtkObject *parentWindow) { return NS_OK; }
00235 
00236   nsresult CreateWidget(nsIWidget *aParent,
00237                         const nsRect &aRect,
00238                         EVENT_CALLBACK aHandleEventFunction,
00239                         nsIDeviceContext *aContext,
00240                         nsIAppShell *aAppShell,
00241                         nsIToolkit *aToolkit,
00242                         nsWidgetInitData *aInitData,
00243                         nsNativeWidget aNativeParent = nsnull);
00244 
00245 
00246   PRBool DispatchWindowEvent(nsGUIEvent* event);
00247 
00248   // this is the "native" destroy code that will destroy any
00249   // native windows / widgets for this logical widget
00250   virtual void DestroyNative(void);
00251 
00252   // Sets font for widgets
00253   virtual void SetFontNative(GdkFont *aFont);
00254   // Sets backround for widgets
00255   virtual void SetBackgroundColorNative(GdkColor *aColorNor,
00256                                         GdkColor *aColorBri,
00257                                         GdkColor *aColorDark);
00258 
00259   // this is set when a given widget has the focus.
00260   PRBool       mHasFocus;
00261 
00262 
00263   // if anyone uses this for public access other than the key
00264   // press/release code on the main window, i will kill you. pav
00265 public:
00266   // this is the current GdkSuperWin with the focus
00267   static nsWidget *sFocusWindow;
00268 
00269 protected:
00270   // 
00271 
00273   //
00274   // GTK signal installers
00275   //
00277   void InstallEnterNotifySignal(GtkWidget * aWidget);
00278 
00279   void InstallLeaveNotifySignal(GtkWidget * aWidget);
00280 
00281   void InstallButtonPressSignal(GtkWidget * aWidget);
00282 
00283   void InstallButtonReleaseSignal(GtkWidget * aWidget);
00284 
00285   virtual
00286   void InstallFocusInSignal(GtkWidget * aWidget);
00287 
00288   virtual
00289   void InstallFocusOutSignal(GtkWidget * aWidget);
00290 
00291   void InstallRealizeSignal(GtkWidget * aWidget);
00292 
00293   void AddToEventMask(GtkWidget * aWidget,
00294                       gint        aEventMask);
00295 
00297   //
00298   // OnSomething handlers
00299   //
00301   virtual void OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent);
00302   virtual void OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
00303   virtual void OnLeaveNotifySignal(GdkEventCrossing * aGdkCrossingEvent);
00304   virtual void OnButtonPressSignal(GdkEventButton * aGdkButtonEvent);
00305   virtual void OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent);
00306   virtual void OnFocusInSignal(GdkEventFocus * aGdkFocusEvent);
00307   virtual void OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent);
00308   virtual void OnRealize(GtkWidget *aWidget);
00309 
00310   virtual void OnDestroySignal(GtkWidget* aGtkWidget);
00311 
00312   // Static method used to trampoline to OnDestroySignal
00313   static gint  DestroySignal(GtkWidget *      aGtkWidget,
00314                              nsWidget*        aWidget);
00315 
00316 public:
00317   virtual void IMECommitEvent(GdkEventKey *aEvent);
00318 
00319   // This MUST be called after you change the widget bounds
00320   // or after the parent's size changes
00321   // or when you show the widget
00322   // We will decide whether to really show the widget or not
00323   // We will hide the widget if it doesn't overlap the parent bounds
00324   // This reduces problems with 16-bit coordinates wrapping.
00325   virtual void ResetInternalVisibility();
00326 
00327   // Reestablish the correct Z-ordering of this widget among
00328   // its siblings
00329   void ResetZOrder();
00330 
00331 protected:
00332   // override this method to do whatever you have to do to make this
00333   // widget visible or invisibile --- i.e., the real work of Show()
00334   virtual void SetInternalVisibility(PRBool aVisible);
00335 
00337   //
00338   // GTK widget signals
00339   //
00341 
00342   static gint EnterNotifySignal(GtkWidget *        aWidget, 
00343                                 GdkEventCrossing * aGdkCrossingEvent, 
00344                                 gpointer           aData);
00345   
00346   static gint LeaveNotifySignal(GtkWidget *        aWidget, 
00347                                 GdkEventCrossing * aGdkCrossingEvent, 
00348                                 gpointer           aData);
00349 
00350   static gint ButtonPressSignal(GtkWidget *      aWidget, 
00351                                 GdkEventButton * aGdkButtonEvent, 
00352                                 gpointer         aData);
00353 
00354   static gint ButtonReleaseSignal(GtkWidget *      aWidget, 
00355                                   GdkEventButton * aGdkButtonEvent, 
00356                                   gpointer         aData);
00357 
00358   static gint RealizeSignal(GtkWidget *      aWidget, 
00359                             gpointer         aData);
00360 
00361 
00362   static gint FocusInSignal(GtkWidget *      aWidget, 
00363                             GdkEventFocus *  aGdkFocusEvent, 
00364                             gpointer         aData);
00365 
00366   static gint FocusOutSignal(GtkWidget *      aWidget, 
00367                              GdkEventFocus *  aGdkFocusEvent, 
00368                              gpointer         aData);
00369 
00370 protected:
00371 
00373   //
00374   // GTK event support methods
00375   //
00377   void InstallSignal(GtkWidget *   aWidget,
00378                      gchar *       aSignalName,
00379                      GtkSignalFunc aSignalFunction);
00380   
00381   void InitMouseEvent(GdkEventButton * aGdkButtonEvent,
00382                       nsMouseEvent &   anEvent);
00383 
00384 #ifdef DEBUG
00385   nsCAutoString  debug_GetName(GtkObject * aGtkWidget);
00386   nsCAutoString  debug_GetName(GtkWidget * aGtkWidget);
00387   PRInt32       debug_GetRenderXID(GtkObject * aGtkWidget);
00388   PRInt32       debug_GetRenderXID(GtkWidget * aGtkWidget);
00389 #endif
00390 
00391   GtkWidget *mWidget;
00392   // our mozbox for those native widgets
00393   GtkWidget *mMozBox;
00394 
00395   nsCOMPtr<nsIWidget> mParent;
00396 
00397   // This is the composite update area (union of all the calls to
00398   // Invalidate)
00399   nsCOMPtr<nsIRegion> mUpdateArea;
00400 
00401   PRUint32 mPreferredWidth, mPreferredHeight;
00402   PRPackedBool mListenForResizes;
00403   PRPackedBool mShown;
00404   PRPackedBool mInternalShown;
00405 
00406   // this is the rollup listener variables
00407   static nsCOMPtr<nsIRollupListener> gRollupListener;
00408   static nsWeakPtr                   gRollupWidget;
00409 
00410   // this is the last time that an event happened.  we keep this
00411   // around so that we can synth drag events properly
00412   static guint32 sLastEventTime;
00413 
00414 private:
00415   // this will keep track of whether or not the gdk handler
00416   // is installed yet
00417   static PRBool mGDKHandlerInstalled;
00418   // this will keep track of whether or not we've told the drag
00419   // service how to call back into us to get the last event time
00420   static PRBool sTimeCBSet;
00421 
00422   //
00423   // Keep track of the last widget being "dragged"
00424   //
00425 public:
00426   static nsWidget *sButtonMotionTarget;
00427   static gint sButtonMotionRootX;
00428   static gint sButtonMotionRootY;
00429   static gint sButtonMotionWidgetX;
00430   static gint sButtonMotionWidgetY;
00431 };
00432 
00433 #endif /* nsWidget_h__ */