Back to index

lightning-sunbird  0.9+nobinonly
nsMenuFrame.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  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 //
00040 // nsMenuFrame
00041 //
00042 
00043 #ifndef nsMenuFrame_h__
00044 #define nsMenuFrame_h__
00045 
00046 #include "prtypes.h"
00047 #include "nsIAtom.h"
00048 #include "nsCOMPtr.h"
00049 
00050 #include "nsBoxFrame.h"
00051 #include "nsFrameList.h"
00052 #include "nsIMenuParent.h"
00053 #include "nsIMenuFrame.h"
00054 #include "nsMenuDismissalListener.h"
00055 #include "nsITimer.h"
00056 #include "nsISupportsArray.h"
00057 #include "nsIDOMText.h"
00058 #include "nsIContent.h"
00059 #include "nsIScrollableViewProvider.h"
00060 
00061 nsresult NS_NewMenuFrame(nsIPresShell* aPresShell, nsIFrame** aResult, PRUint32 aFlags) ;
00062 
00063 class nsMenuBarFrame;
00064 class nsMenuPopupFrame;
00065 class nsIScrollableView;
00066 
00067 #define NS_STATE_ACCELTEXT_IS_DERIVED  NS_STATE_BOX_CHILD_RESERVED
00068 
00069 class nsMenuFrame;
00070 
00078 class nsMenuTimerMediator : public nsITimerCallback
00079 {
00080 public:
00081   nsMenuTimerMediator(nsMenuFrame* aFrame);
00082   ~nsMenuTimerMediator();
00083 
00084   NS_DECL_ISUPPORTS
00085   NS_DECL_NSITIMERCALLBACK
00086 
00087   void ClearFrame();
00088 
00089 private:
00090 
00091   // Pointer to the wrapped frame.
00092   nsMenuFrame* mFrame;
00093 };
00094 
00101 class nsMenuFrame : public nsBoxFrame, 
00102                     public nsIMenuFrame,
00103                     public nsIScrollableViewProvider
00104 {
00105 public:
00106   nsMenuFrame(nsIPresShell* aShell);
00107 
00108   NS_DECL_ISUPPORTS
00109 
00110   // nsIBox
00111   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
00112   NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
00113   NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
00114 
00115   NS_IMETHOD Init(nsPresContext*  aPresContext,
00116                   nsIContent*      aContent,
00117                   nsIFrame*        aParent,
00118                   nsStyleContext*  aContext,
00119                   nsIFrame*        aPrevInFlow);
00120 
00121 #ifdef DEBUG_LAYOUT
00122   NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug);
00123 #endif
00124 
00125   NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; };
00126 
00127   // The following four methods are all overridden so that the menu children
00128   // can be stored in a separate list (so that they don't impact reflow of the
00129   // actual menu item at all).
00130   virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
00131   NS_IMETHOD SetInitialChildList(nsPresContext* aPresContext,
00132                                  nsIAtom*        aListName,
00133                                  nsIFrame*       aChildList);
00134   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
00135   NS_IMETHOD Destroy(nsPresContext* aPresContext); // @see comment ***
00136 
00137   // Overridden to prevent events from ever going to children of the menu.
00138   NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint,
00139                               nsFramePaintLayer aWhichLayer,    
00140                               nsIFrame**     aFrame);
00141 
00142   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
00143                          nsGUIEvent*     aEvent,
00144                          nsEventStatus*  aEventStatus); // @see comment ***
00145 
00146   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
00147                            nsIFrame*       aFrameList);
00148 
00149   NS_IMETHOD  InsertFrames(nsIAtom*        aListName,
00150                            nsIFrame*       aPrevFrame,
00151                            nsIFrame*       aFrameList);
00152 
00153   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
00154                           nsIFrame*       aOldFrame);
00155 
00156   // nsIMenuFrame Interface
00157 
00158   NS_IMETHOD ActivateMenu(PRBool aActivateFlag); // @see comment **
00159   NS_IMETHOD SelectMenu(PRBool aActivateFlag); // @see comment ***
00160   NS_IMETHOD OpenMenu(PRBool aActivateFlag); // @see comment ***
00161 
00162   NS_IMETHOD MenuIsOpen(PRBool& aResult) { aResult = IsOpen(); return NS_OK; }
00163   NS_IMETHOD MenuIsContainer(PRBool& aResult) { aResult = IsMenu(); return NS_OK; }
00164   NS_IMETHOD MenuIsChecked(PRBool& aResult) { aResult = mChecked; return NS_OK; }
00165   NS_IMETHOD MenuIsDisabled(PRBool& aResult) { aResult = IsDisabled(); return NS_OK; }
00166   
00167   NS_IMETHOD GetActiveChild(nsIDOMElement** aResult);
00168   NS_IMETHOD SetActiveChild(nsIDOMElement* aChild); // @see comment ***
00169 
00170   NS_IMETHOD UngenerateMenu(); // @see comment ***
00171 
00172   NS_IMETHOD SelectFirstItem(); // @see comment ***
00173 
00174   NS_IMETHOD Escape(PRBool& aHandledFlag); // @see comment ***
00175   NS_IMETHOD Enter(); // @see comment ***
00176   NS_IMETHOD ShortcutNavigation(nsIDOMKeyEvent* aKeyEvent, PRBool& aHandledFlag); // @see comment ***
00177   NS_IMETHOD KeyboardNavigation(PRUint32 aKeyCode, PRBool& aHandledFlag); // @see comment ***
00178 
00179   NS_IMETHOD SetParent(const nsIFrame* aParent);
00180 
00181   virtual nsIMenuParent *GetMenuParent() { return mMenuParent; };
00182   virtual nsIFrame *GetMenuChild() { return mPopupFrames.FirstChild(); }
00183   NS_IMETHOD GetRadioGroupName(nsString &aName) { aName = mGroupName; return NS_OK; };
00184   NS_IMETHOD GetMenuType(nsMenuType &aType) { aType = mType; return NS_OK; };
00185   NS_IMETHOD MarkChildrenStyleChange();
00186   NS_IMETHOD MarkAsGenerated();
00187 
00188   // nsIScrollableViewProvider methods
00189 
00190   virtual nsIScrollableView* GetScrollableView();
00191 
00192   // nsMenuFrame methods 
00193 
00194   nsresult DestroyPopupFrames(nsPresContext* aPresContext);
00195 
00196   PRBool IsOpen() { return mMenuOpen; };
00197   PRBool IsMenu();
00198   PRBool IsDisabled();
00199   PRBool IsGenerated();
00200   NS_IMETHOD ToggleMenuState(); // @see comment ***
00201 
00202   void SetIsMenu(PRBool aIsMenu) { mIsMenu = aIsMenu; };
00203 
00204 #ifdef DEBUG
00205   NS_IMETHOD GetFrameName(nsAString& aResult) const
00206   {
00207       return MakeFrameName(NS_LITERAL_STRING("Menu"), aResult);
00208   }
00209 #endif
00210 
00211   static PRBool IsSizedToPopup(nsIContent* aContent, PRBool aRequireAlways);
00212 
00213   static nsIMenuParent *GetContextMenu();
00214 
00215 protected:
00216   friend class nsMenuTimerMediator;
00217   
00218   virtual void RePositionPopup(nsBoxLayoutState& aState);
00219 
00220   void  ConvertPosition(nsIContent* aPopupElt, nsString& aAnchor, nsString& aAlign);
00221 
00222   static void UpdateDismissalListener(nsIMenuParent* aMenuParent);
00223   friend class nsASyncMenuInitialization;
00224   void UpdateMenuType(nsPresContext* aPresContext); // @see comment ***
00225   void UpdateMenuSpecialState(nsPresContext* aPresContext); // @see comment ***
00226 
00227   void OpenMenuInternal(PRBool aActivateFlag); // @see comment ***
00228   void GetMenuChildrenElement(nsIContent** aResult);
00229 
00230   // Examines the key node and builds the accelerator.
00231   void BuildAcceleratorText(); // @see comment ***
00232 
00233   // Called to execute our command handler.
00234   void Execute(nsGUIEvent *aEvent); // @see comment ***
00235 
00236   // Called as a hook just before the menu gets opened.
00237   PRBool OnCreate(); // @see comment ***
00238 
00239   // Called as a hook just after the menu gets opened.
00240   PRBool OnCreated(); // @see comment ***
00241 
00242   // Called as a hook just before the menu goes away.
00243   PRBool OnDestroy(); // @see comment ***
00244 
00245   // Called as a hook just after the menu goes away.
00246   PRBool OnDestroyed(); // @see comment ***
00247 
00248   NS_IMETHOD AttributeChanged(nsIContent* aChild,
00249                               PRInt32 aNameSpaceID,
00250                               nsIAtom* aAttribute,
00251                               PRInt32 aModType); // @see comment ***
00252   virtual ~nsMenuFrame();
00253 
00254   PRBool SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize);
00255 
00256 protected:
00257 #ifdef DEBUG_LAYOUT
00258   nsresult SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug);
00259 #endif
00260   NS_HIDDEN_(nsresult) Notify(nsITimer* aTimer);
00261 
00262   nsFrameList mPopupFrames;
00263   PRPackedBool mIsMenu; // Whether or not we can even have children or not.
00264   PRPackedBool mMenuOpen;
00265   PRPackedBool mCreateHandlerSucceeded;  // Did the create handler succeed?
00266   PRPackedBool mChecked;              // are we checked?
00267   nsMenuType mType;
00268 
00269   nsIMenuParent* mMenuParent; // Our parent menu.
00270 
00271   // Reference to the mediator which wraps this frame.
00272   nsRefPtr<nsMenuTimerMediator> mTimerMediator;
00273 
00274   nsCOMPtr<nsITimer> mOpenTimer;
00275 
00276   nsPresContext* mPresContext; // Our pres context.
00277   nsString mGroupName;
00278   nsSize mLastPref;
00279   
00280   //we load some display strings from platformKeys.properties only once
00281   static nsrefcnt gRefCnt; 
00282   static nsString *gShiftText;
00283   static nsString *gControlText;
00284   static nsString *gMetaText;
00285   static nsString *gAltText;
00286   static nsString *gModifierSeparator;
00287 
00288 public:
00289   static nsMenuDismissalListener* sDismissalListener; // The listener that dismisses menus.
00290 }; // class nsMenuFrame
00291 
00292 #endif