Back to index

lightning-sunbird  0.9+nobinonly
nsButtonBoxFrame.cpp
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 Communicator client 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  *   Blake Ross (blakeross@telocity.com)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 #include "nsCOMPtr.h"
00040 #include "nsButtonBoxFrame.h"
00041 #include "nsIContent.h"
00042 #include "nsIDocument.h"
00043 #include "nsIDOMDocument.h"
00044 #include "nsIDOMNodeList.h"
00045 #include "nsIDOMXULButtonElement.h"
00046 #include "nsHTMLAtoms.h"
00047 #include "nsINameSpaceManager.h"
00048 #include "nsPresContext.h"
00049 #include "nsIPresShell.h"
00050 #include "nsGUIEvent.h"
00051 #include "nsIEventStateManager.h"
00052 #include "nsXULAtoms.h"
00053 #include "nsIDOMElement.h"
00054 
00055 //
00056 // NS_NewXULButtonFrame
00057 //
00058 // Creates a new Button frame and returns it in |aNewFrame|
00059 //
00060 nsresult
00061 NS_NewButtonBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
00062 {
00063   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00064   if (nsnull == aNewFrame) {
00065     return NS_ERROR_NULL_POINTER;
00066   }
00067   nsButtonBoxFrame* it = new (aPresShell) nsButtonBoxFrame(aPresShell);
00068   if (nsnull == it)
00069     return NS_ERROR_OUT_OF_MEMORY;
00070 
00071   // it->SetFlags(aFlags);
00072   *aNewFrame = it;
00073   return NS_OK;
00074   
00075 } // NS_NewXULButtonFrame
00076 
00077 nsButtonBoxFrame::nsButtonBoxFrame(nsIPresShell* aPresShell)
00078 :nsBoxFrame(aPresShell, PR_FALSE)
00079 {
00080 }
00081 
00082 NS_IMETHODIMP
00083 nsButtonBoxFrame::GetMouseThrough(PRBool& aMouseThrough)
00084 {
00085   aMouseThrough = PR_FALSE;
00086   return NS_OK;
00087 }
00088 
00089 NS_IMETHODIMP nsButtonBoxFrame::GetFrameForPoint(const nsPoint& aPoint, 
00090                                     nsFramePaintLayer aWhichLayer,
00091                                     nsIFrame**     aFrame)
00092 {
00093   // override, since we don't want children to get events
00094   return nsFrame::GetFrameForPoint(aPoint, aWhichLayer, aFrame);
00095 }
00096 
00097 NS_IMETHODIMP
00098 nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext, 
00099                               nsGUIEvent* aEvent,
00100                               nsEventStatus* aEventStatus)
00101 {
00102   switch (aEvent->message) {
00103     case NS_KEY_DOWN:
00104       if (NS_KEY_EVENT == aEvent->eventStructType) {
00105         nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
00106         if (NS_VK_SPACE == keyEvent->keyCode) {
00107           nsIEventStateManager *esm = aPresContext->EventStateManager();
00108           // :hover:active state
00109           esm->SetContentState(mContent,
00110                                NS_EVENT_STATE_HOVER |  NS_EVENT_STATE_ACTIVE);
00111         }
00112       }
00113       break;
00114 
00115 // On mac, Return fires the defualt button, not the focused one.
00116 #ifndef XP_MACOSX
00117     case NS_KEY_PRESS:
00118       if (NS_KEY_EVENT == aEvent->eventStructType) {
00119         nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
00120         if (NS_VK_RETURN == keyEvent->keyCode) {
00121           nsCOMPtr<nsIDOMXULButtonElement> buttonEl(do_QueryInterface(mContent));
00122           if (buttonEl) {
00123             MouseClicked(aPresContext, aEvent);
00124             *aEventStatus = nsEventStatus_eConsumeNoDefault;
00125           }
00126         }
00127       }
00128       break;
00129 #endif
00130 
00131     case NS_KEY_UP:
00132       if (NS_KEY_EVENT == aEvent->eventStructType) {
00133         nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
00134         if (NS_VK_SPACE == keyEvent->keyCode) {
00135           // only activate on keyup if we're already in the :hover:active state
00136           PRInt32 buttonState;
00137           const PRInt32 activeHover = NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER;
00138           nsIEventStateManager *esm = aPresContext->EventStateManager();
00139           esm->GetContentState(mContent, buttonState);
00140           if ((buttonState & activeHover) == activeHover) {
00141             esm->SetContentState(nsnull, activeHover);    // return to normal state
00142             MouseClicked(aPresContext, aEvent);
00143           }
00144         }
00145       }
00146       break;
00147 
00148     case NS_MOUSE_LEFT_CLICK:
00149       MouseClicked(aPresContext, aEvent);
00150       break;
00151   }
00152 
00153   return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
00154 }
00155 
00156 void 
00157 nsButtonBoxFrame::DoMouseClick(nsGUIEvent* aEvent, PRBool aTrustEvent) 
00158 {
00159   // Don't execute if we're disabled.
00160   nsAutoString disabled;
00161   mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
00162   if (disabled.EqualsLiteral("true"))
00163     return;
00164 
00165   // Execute the oncommand event handler.
00166   nsEventStatus status = nsEventStatus_eIgnore;
00167   nsXULCommandEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : aTrustEvent,
00168                           NS_XUL_COMMAND, nsnull);
00169   if(aEvent) {
00170     event.isShift = ((nsInputEvent*)(aEvent))->isShift;
00171     event.isControl = ((nsInputEvent*)(aEvent))->isControl;
00172     event.isAlt = ((nsInputEvent*)(aEvent))->isAlt;
00173     event.isMeta = ((nsInputEvent*)(aEvent))->isMeta;
00174   }
00175 
00176   // Have the content handle the event, propagating it according to normal DOM rules.
00177   nsCOMPtr<nsIPresShell> shell = GetPresContext()->GetPresShell();
00178   if (shell) {
00179     shell->HandleDOMEventWithTarget(mContent, &event, &status);
00180   }
00181 }