Back to index

lightning-sunbird  0.9+nobinonly
nsMenuPopupFrame.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  *   Original Author: David W. Hyatt (hyatt@netscape.com)
00024  *   Mike Pinkerton (pinkerton@netscape.com)
00025  *   Dean Tessman <dean_tessman@hotmail.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 //
00042 // nsMenuPopupFrame
00043 //
00044 
00045 #ifndef nsMenuPopupFrame_h__
00046 #define nsMenuPopupFrame_h__
00047 
00048 #include "prtypes.h"
00049 #include "nsIAtom.h"
00050 #include "nsCOMPtr.h"
00051 #include "nsIDOMEventReceiver.h"
00052 #include "nsMenuListener.h"
00053 
00054 #include "nsBoxFrame.h"
00055 #include "nsIMenuParent.h"
00056 #include "nsIWidget.h"
00057 #include "nsLayoutAtoms.h"
00058 
00059 #include "nsITimer.h"
00060 
00061 #define INC_TYP_INTERVAL  1000  // 1s. If the interval between two keypresses is shorter than this, 
00062                                 //   treat as a continue typing
00063 // XXX, kyle.yuan@sun.com, there are 4 definitions for the same purpose:
00064 //  nsMenuPopupFrame.h, nsListControlFrame.cpp, listbox.xml, tree.xml
00065 //  need to find a good place to put them together.
00066 //  if someone changes one, please also change the other.
00067 
00068 nsresult NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ;
00069 
00070 class nsIViewManager;
00071 class nsIView;
00072 class nsIMenuParent;
00073 class nsIMenuFrame;
00074 class nsIDOMXULDocument;
00075 
00076 class nsMenuPopupFrame;
00077 
00085 class nsMenuPopupTimerMediator : public nsITimerCallback
00086 {
00087 public:
00088   nsMenuPopupTimerMediator(nsMenuPopupFrame* aFrame);
00089   ~nsMenuPopupTimerMediator();
00090 
00091   NS_DECL_ISUPPORTS
00092   NS_DECL_NSITIMERCALLBACK
00093 
00094   void ClearFrame();
00095 
00096 private:
00097 
00098   // Pointer to the wrapped frame.
00099   nsMenuPopupFrame* mFrame;
00100 };
00101 
00102 class nsMenuPopupFrame : public nsBoxFrame, public nsIMenuParent
00103 {
00104 public:
00105   nsMenuPopupFrame(nsIPresShell* aShell);
00106 
00107   NS_DECL_ISUPPORTS
00108 
00109 
00110   // nsIMenuParentInterface
00111   virtual nsIMenuFrame* GetCurrentMenuItem();
00112   NS_IMETHOD SetCurrentMenuItem(nsIMenuFrame* aMenuItem);
00113   virtual nsIMenuFrame* GetNextMenuItem(nsIMenuFrame* aStart);
00114   virtual nsIMenuFrame* GetPreviousMenuItem(nsIMenuFrame* aStart);
00115   NS_IMETHOD SetActive(PRBool aActiveFlag) { return NS_OK; }; // We don't care.
00116   NS_IMETHOD GetIsActive(PRBool& isActive) { isActive = PR_FALSE; return NS_OK; };
00117   NS_IMETHOD IsMenuBar(PRBool& isMenuBar) { isMenuBar = PR_FALSE; return NS_OK; };
00118   NS_IMETHOD ConsumeOutsideClicks(PRBool& aConsumeOutsideClicks);
00119   NS_IMETHOD ClearRecentlyRolledUp() {return NS_OK;}
00120   NS_IMETHOD RecentlyRolledUp(nsIMenuFrame *aMenuFrame, PRBool *aJustRolledUp) {*aJustRolledUp = PR_FALSE; return NS_OK;}
00121   NS_IMETHOD SetIsContextMenu(PRBool aIsContextMenu) { mIsContextMenu = aIsContextMenu; return NS_OK; };
00122   NS_IMETHOD GetIsContextMenu(PRBool& aIsContextMenu) { aIsContextMenu = mIsContextMenu; return NS_OK; };
00123   
00124   NS_IMETHOD GetParentPopup(nsIMenuParent** aResult);
00125 
00126   // Closes up the chain of open cascaded menus.
00127   NS_IMETHOD DismissChain();
00128 
00129   // Hides the chain of cascaded menus without closing them up.
00130   NS_IMETHOD HideChain();
00131 
00132   NS_IMETHOD KillPendingTimers();
00133 
00134   NS_IMETHOD InstallKeyboardNavigator();
00135   NS_IMETHOD RemoveKeyboardNavigator();
00136 
00137   NS_IMETHOD GetWidget(nsIWidget **aWidget);
00138 
00139   // The dismissal listener gets created and attached to the window.
00140   NS_IMETHOD CreateDismissalListener();
00141 
00142   // Overridden methods
00143   NS_IMETHOD Init(nsPresContext*  aPresContext,
00144                   nsIContent*      aContent,
00145                   nsIFrame*        aParent,
00146                   nsStyleContext*  aContext,
00147                   nsIFrame*        aPrevInFlow);
00148 
00149   NS_IMETHOD AttributeChanged(nsIContent* aChild,
00150                               PRInt32 aNameSpaceID,
00151                               nsIAtom* aAttribute,
00152                               PRInt32 aModType);
00153 
00154   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
00155                          nsGUIEvent*     aEvent,
00156                          nsEventStatus*  aEventStatus);
00157 
00158   NS_IMETHOD Destroy(nsPresContext* aPresContext);
00159 
00160   NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint,
00161                               nsFramePaintLayer aWhichLayer,    
00162                               nsIFrame**     aFrame);
00163 
00164   NS_IMETHOD MarkStyleChange(nsBoxLayoutState& aState);
00165   NS_IMETHOD MarkDirty(nsBoxLayoutState& aState);
00166   NS_IMETHOD RelayoutDirtyChild(nsBoxLayoutState& aState, nsIBox* aChild);
00167 
00168   void GetViewOffset(nsIView* aView, nsPoint& aPoint);
00169   static void GetRootViewForPopup(nsIFrame* aStartFrame,
00170                                   PRBool aStopAtViewManagerRoot,
00171                                   nsIView** aResult);
00172 
00173   nsresult SyncViewWithFrame(nsPresContext* aPresContext, const nsString& aPopupAnchor,
00174                              const nsString& aPopupAlign,
00175                              nsIFrame* aFrame, PRInt32 aXPos, PRInt32 aYPos);
00176 
00177   NS_IMETHOD KeyboardNavigation(PRUint32 aKeyCode, PRBool& aHandledFlag);
00178   NS_IMETHOD ShortcutNavigation(nsIDOMKeyEvent* aKeyEvent, PRBool& aHandledFlag);
00179   
00180   NS_IMETHOD Escape(PRBool& aHandledFlag);
00181   NS_IMETHOD Enter();
00182 
00183   nsIMenuFrame* FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, PRBool& doAction);
00184 
00185   PRBool IsValidItem(nsIContent* aContent);
00186   PRBool IsDisabled(nsIContent* aContent);
00187 
00188   nsIMenuParent* GetContextMenu();
00189 
00190   NS_IMETHOD KillCloseTimer();
00191 
00192   virtual nsIAtom* GetType() const { return nsLayoutAtoms::menuPopupFrame; }
00193 
00194 #ifdef DEBUG
00195   NS_IMETHOD GetFrameName(nsAString& aResult) const
00196   {
00197       return MakeFrameName(NS_LITERAL_STRING("MenuPopup"), aResult);
00198   }
00199 #endif
00200 
00201   void EnsureMenuItemIsVisible(nsIMenuFrame* aMenuFrame);
00202 
00203   // This sets 'left' and 'top' attributes.
00204   // May kill the frame.
00205   void MoveTo(PRInt32 aLeft, PRInt32 aTop);
00206 
00207   void GetAutoPosition(PRBool* aShouldAutoPosition);
00208   void SetAutoPosition(PRBool aShouldAutoPosition);
00209   void EnableRollup(PRBool aShouldRollup);
00210 
00211   nsIScrollableView* GetScrollableView(nsIFrame* aStart);
00212   
00213 protected:
00214   friend class nsMenuPopupTimerMediator;
00215   NS_HIDDEN_(nsresult) Notify(nsITimer* aTimer);
00216 
00217   // Move without updating attributes.
00218   void MoveToInternal(PRInt32 aLeft, PRInt32 aTop);
00219 
00220   // redefine to tell the box system not to move the
00221   // views.
00222   virtual void GetLayoutFlags(PRUint32& aFlags);
00223 
00224   // given x,y in client coordinates, compensate for nested documents like framesets.
00225   void AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell, 
00226                                             PRInt32 inClientX, PRInt32 inClientY, 
00227                                             PRInt32* outAdjX, PRInt32* outAdjY ) ;
00228 
00229   void AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsRect & inParentRect,
00230                                         const nsString& aPopupAnchor, const nsString& aPopupAlign,
00231                                         PRBool* outFlushWithTopBottom ) ;
00232 
00233   PRBool IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY,
00234                                            const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
00235                                            PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ;
00236 
00237   void MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos, 
00238                                            PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY,
00239                                            const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
00240                                            PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ;
00241 
00242   // Move the popup to the position specified in its |left| and |top| attributes.
00243   void MoveToAttributePosition();
00244 
00245 
00246   nsIMenuFrame* mCurrentMenu; // The current menu that is active.
00247   // XXX Hack
00248   nsPresContext* mPresContext;  // weak reference
00249 
00250   nsMenuListener* mKeyboardNavigator; // The listener that tells us about key events.
00251   nsIDOMEventReceiver* mTarget;
00252 
00253   nsIMenuFrame* mTimerMenu; // A menu awaiting closure.
00254   nsCOMPtr<nsITimer> mCloseTimer; // Close timer.
00255 
00256   // Reference to the mediator which wraps this frame.
00257   nsRefPtr<nsMenuPopupTimerMediator> mTimerMediator;
00258 
00259   PRPackedBool mIsContextMenu;  // is this a context menu?
00260   
00261   PRPackedBool mMenuCanOverlapOSBar;    // can we appear over the taskbar/menubar?
00262 
00263   PRPackedBool mShouldAutoPosition; // Should SyncViewWithFrame be allowed to auto position popup?
00264   PRPackedBool mShouldRollup; // Should this menupopup be allowed to dismiss automatically?
00265   PRPackedBool mInContentShell; // True if the popup is in a content shell
00266 
00267   nsString     mIncrementalString;  // for incremental typing navigation
00268 
00269 }; // class nsMenuPopupFrame
00270 
00271 #endif