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 "nsIKBStateControl.h"
00043 #include "nsIRegion.h"
00044 #ifdef PHOTON_DND
00045 #include "nsIDragService.h"
00046 #endif
00047 #include "nsClipboard.h"
00048 
00049 class nsILookAndFeel;
00050 class nsIAppShell;
00051 class nsIToolkit;
00052 
00053 #include <Pt.h>
00054 
00055 class nsWidget;
00056 
00057 #define NS_TO_PH_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
00058 #define PH_TO_NS_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
00059 
00064 class nsWidget : public nsBaseWidget, nsIKBStateControl
00065 {
00066 public:
00067   nsWidget();
00068   virtual ~nsWidget();
00069 
00070   NS_DECL_ISUPPORTS_INHERITED
00071 
00072   // nsIWidget
00073 
00074        // create with nsIWidget parent
00075   inline NS_IMETHOD            Create(nsIWidget *aParent,
00076                                const nsRect &aRect,
00077                                EVENT_CALLBACK aHandleEventFunction,
00078                                nsIDeviceContext *aContext,
00079                                nsIAppShell *aAppShell = nsnull,
00080                                nsIToolkit *aToolkit = nsnull,
00081                                nsWidgetInitData *aInitData = nsnull)
00082               {
00083               return(CreateWidget(aParent, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData, nsnull));
00084               }
00085 
00086        // create with a native parent
00087   inline NS_IMETHOD            Create(nsNativeWidget aParent,
00088                                const nsRect &aRect,
00089                                EVENT_CALLBACK aHandleEventFunction,
00090                                nsIDeviceContext *aContext,
00091                                nsIAppShell *aAppShell = nsnull,
00092                                nsIToolkit *aToolkit = nsnull,
00093                                nsWidgetInitData *aInitData = nsnull)
00094               {
00095               return(CreateWidget(nsnull, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData,aParent));
00096               }
00097 
00098   NS_IMETHOD Destroy(void);
00099   inline nsIWidget* GetParent(void)
00100               {
00101               if( mIsDestroying ) return nsnull;
00102               nsIWidget* result = mParent;
00103               if( mParent ) NS_ADDREF( result );
00104               return result;
00105               }
00106 
00107   virtual void OnDestroy();
00108 
00109   NS_IMETHOD SetModal(PRBool aModal);
00110   NS_IMETHOD Show(PRBool state);
00111   inline NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) { return NS_OK; }
00112 
00113   inline NS_IMETHOD IsVisible(PRBool &aState) { aState = mShown; return NS_OK; }
00114 
00115   inline NS_IMETHOD ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY) { return NS_OK; }
00116   NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
00117   NS_IMETHOD Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint);
00118   inline NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
00119               {
00120               Move(aX,aY);
00121               Resize(aWidth,aHeight,aRepaint);
00122               return NS_OK;
00123               }
00124 
00125   inline NS_IMETHOD Enable(PRBool aState)
00126               {
00127               if( mWidget ) PtSetResource( mWidget, Pt_ARG_FLAGS, aState ? 0 : Pt_BLOCKED, Pt_BLOCKED );
00128               return NS_OK;
00129               }
00130 
00131   inline NS_IMETHOD IsEnabled(PRBool *aState)
00132               {
00133               if(PtWidgetFlags(mWidget) & Pt_BLOCKED) *aState = PR_FALSE;
00134               else *aState = PR_TRUE;
00135               return NS_OK;
00136               }
00137 
00138   PRBool OnResize(nsSizeEvent event);
00139   virtual PRBool OnResize(nsRect &aRect);
00140   virtual PRBool OnMove(PRInt32 aX, PRInt32 aY);
00141 
00142   inline nsIFontMetrics *GetFont(void) { return nsnull; }
00143   NS_IMETHOD SetFont(const nsFont &aFont);
00144 
00145   inline NS_IMETHOD SetBackgroundColor(const nscolor &aColor)
00146               {
00147               nsBaseWidget::SetBackgroundColor( aColor );
00148               if( mWidget ) PtSetResource( mWidget, Pt_ARG_FILL_COLOR, NS_TO_PH_RGB( aColor ), 0 );
00149               return NS_OK;
00150               }
00151 
00152   NS_IMETHOD SetCursor(nsCursor aCursor);
00153 
00154   inline NS_IMETHOD SetColorMap(nsColorMap *aColorMap) { return NS_OK; }
00155 
00156   inline void* GetNativeData(PRUint32 aDataType) { return (void *)mWidget; }
00157 
00158   NS_IMETHOD WidgetToScreen(const nsRect &aOldRect, nsRect &aNewRect);
00159   NS_IMETHOD ScreenToWidget(const nsRect &aOldRect, nsRect &aNewRect);
00160 
00161   inline NS_IMETHOD BeginResizingChildren(void)
00162               {
00163               PtHold();
00164               return NS_OK;
00165               }
00166 
00167   inline NS_IMETHOD EndResizingChildren(void)
00168               {
00169               PtRelease();
00170               return NS_OK;
00171               }
00172 
00173   inline NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight)
00174               {
00175               aWidth  = mPreferredWidth;
00176               aHeight = mPreferredHeight;
00177               return (mPreferredWidth != 0 && mPreferredHeight != 0)?NS_OK:NS_ERROR_FAILURE;
00178               }
00179 
00180   inline NS_IMETHOD SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight)
00181               {
00182               mPreferredWidth  = aWidth;
00183               mPreferredHeight = aHeight;
00184               return NS_OK;
00185               }
00186 
00187   // Use this to set the name of a widget for normal widgets.. not the same as the nsWindow version
00188   inline NS_IMETHOD SetTitle(const nsAString& aTitle) { return NS_OK; }
00189 
00190   inline void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY) { }
00191 
00192   // the following are nsWindow specific, and just stubbed here
00193   inline NS_IMETHOD Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) { return NS_OK; }
00194   inline NS_IMETHOD ScrollWidgets(PRInt32 aDx, PRInt32 aDy) { return NS_OK; }
00195  
00196   inline NS_IMETHOD SetMenuBar(nsIMenuBar *aMenuBar) { return NS_ERROR_FAILURE; }
00197   inline NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
00198   // *could* be done on a widget, but that would be silly wouldn't it?
00199   NS_IMETHOD CaptureMouse(PRBool aCapture) { return NS_ERROR_FAILURE; }
00200 
00201 
00202   NS_IMETHOD Invalidate(PRBool aIsSynchronous);
00203   NS_IMETHOD Invalidate(const nsRect &aRect, PRBool aIsSynchronous);
00204   NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
00205   inline NS_IMETHOD Update(void)
00206               {
00207               /* if the widget has been invalidated or damaged then re-draw it */
00208               PtFlush();
00209               return NS_OK;
00210               }
00211 
00212   NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
00213 
00214 
00215   // nsIKBStateControl
00216   NS_IMETHOD ResetInputState();
00217   NS_IMETHOD SetIMEOpenState(PRBool aState);
00218   NS_IMETHOD GetIMEOpenState(PRBool* aState);
00219   NS_IMETHOD CancelIMEComposition();
00220 
00221   inline void InitEvent(nsGUIEvent& event, PRUint32 aEventType, nsPoint* aPoint = nsnull)
00222               {
00223               if( aPoint == nsnull ) {
00224                 event.point.x = 0;
00225                 event.point.y = 0;
00226                 }
00227               else {
00228                 event.point.x = aPoint->x;
00229                 event.point.y = aPoint->y;
00230                 }
00231               event.widget = this;
00232               event.time = PR_IntervalNow();
00233               event.message = aEventType;
00234               }
00235 
00236   // Utility functions
00237 
00238   inline PRBool     ConvertStatus(nsEventStatus aStatus)
00239               {
00240               switch(aStatus) {
00241                 case nsEventStatus_eIgnore:
00242                 case nsEventStatus_eConsumeDoDefault:
00243                   return(PR_FALSE);
00244                 case nsEventStatus_eConsumeNoDefault:
00245                   return(PR_TRUE);
00246                 }
00247               NS_ASSERTION(0, "Illegal nsEventStatus enumeration value");
00248               return PR_FALSE;
00249               }
00250 
00251   PRBool     DispatchMouseEvent(nsMouseEvent& aEvent);
00252   inline PRBool     DispatchStandardEvent(PRUint32 aMsg)
00253               {
00254               nsGUIEvent event(PR_TRUE, 0, nsnull);
00255               InitEvent(event, aMsg);
00256               return DispatchWindowEvent(&event);
00257               }
00258 
00259   // are we a "top level" widget?
00260   PRBool     mIsToplevel;
00261 
00262   // Set/Get the Pt_ARG_USER_DATA associated with each PtWidget_t *
00263   // this is always set to the "this" that owns the PtWidget_t
00264   static inline void SetInstance( PtWidget_t *pWidget, nsWidget * inst ) { PtSetResource( pWidget, Pt_ARG_POINTER, (void *)inst, 0 ); }
00265   static inline nsWidget*  GetInstance( PtWidget_t *pWidget )
00266               {
00267               nsWidget *data;
00268               PtGetResource( pWidget, Pt_ARG_POINTER, &data, 0 );
00269               return data;
00270               }
00271 
00272 protected:
00273   NS_IMETHOD CreateNative(PtWidget_t *parentWindow) { return NS_OK; }
00274 
00275   nsresult CreateWidget(nsIWidget *aParent,
00276                         const nsRect &aRect,
00277                         EVENT_CALLBACK aHandleEventFunction,
00278                         nsIDeviceContext *aContext,
00279                         nsIAppShell *aAppShell,
00280                         nsIToolkit *aToolkit,
00281                         nsWidgetInitData *aInitData,
00282                         nsNativeWidget aNativeParent = nsnull);
00283 
00284   inline PRBool DispatchWindowEvent(nsGUIEvent* event)
00285               {
00286               nsEventStatus status;
00287               DispatchEvent(event, status);
00288               return ConvertStatus(status);
00289               }
00290 
00291 #ifdef PHOTON_DND
00292        void DispatchDragDropEvent( PhEvent_t *phevent, PRUint32 aEventType, PhPoint_t *pos );
00293        void ProcessDrag( PhEvent_t *event, PRUint32 aEventType, PhPoint_t *pos );
00294 #endif
00295 
00296   // this is the "native" destroy code that will destroy any
00297   // native windows / widgets for this logical widget
00298   virtual void DestroyNative(void);
00299 
00301   //
00302   // Photon event support methods
00303   //
00305   static int      RawEventHandler( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo );
00306   inline PRBool             HandleEvent( PtWidget_t *, PtCallbackInfo_t* aCbInfo );
00307   PRBool          DispatchKeyEvent(PhKeyEvent_t *aPhKeyEvent, int force);
00308 
00309   inline void ScreenToWidgetPos( PhPoint_t &pt )
00310               {
00311               // pt is in screen coordinates - convert it to be relative to ~this~ widgets origin
00312               short x, y;
00313               PtGetAbsPosition( mWidget, &x, &y );
00314               pt.x -= x; pt.y -= y;
00315               }
00316 
00317        inline void InitKeyEvent(PhKeyEvent_t *aPhKeyEvent, nsKeyEvent &anEvent );
00318        inline void InitKeyPressEvent(PhKeyEvent_t *aPhKeyEvent, nsKeyEvent &anEvent );
00319   void InitMouseEvent( PhPointerEvent_t * aPhButtonEvent,
00320                        nsWidget         * aWidget,
00321                        nsMouseEvent     & anEvent,
00322                        PRUint32         aEventType );
00323 
00324 
00325   /* Convert Photon key codes to Mozilla key codes */
00326   PRUint32 nsConvertKey( PhKeyEvent_t *aPhKeyEvent );
00327 
00328 #if 0
00329   //Enable/Disable Photon Damage            
00330        inline void EnableDamage( PtWidget_t *widget, PRBool enable )
00331               {
00332               PtWidget_t *top = PtFindDisjoint( widget );
00333               if( top ) {
00334                      if( PR_TRUE == enable ) PtEndFlux( top );
00335                      else PtStartFlux( top );
00336                      }
00337               }
00338 #endif
00339 
00340 
00342   //
00343   // Photon widget callbacks
00344   //
00346   static int  GotFocusCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo );
00347   static int  LostFocusCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo );
00348   static int  DestroyedCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo );
00349 #ifdef PHOTON_DND
00350   static int  DndCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo );
00351 #endif
00352 
00353   PtWidget_t          *mWidget;
00354   nsIWidget                                      *mParent;
00355   PRBool mShown;
00356 
00357   PRUint32 mPreferredWidth, mPreferredHeight;
00358   PRBool       mListenForResizes;
00359    
00360   // Focus used global variable
00361   static nsWidget* sFocusWidget; //Current Focus Widget
00362   
00363   static nsILookAndFeel *sLookAndFeel;
00364 #ifdef PHOTON_DND
00365        static nsIDragService *sDragService;
00366 #endif
00367        static nsClipboard *sClipboard;
00368   static PRUint32 sWidgetCount;
00369 };
00370 
00371 #endif /* nsWidget_h__ */