layout/xul/nsButtonBoxFrame.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsCOMPtr.h"
     6 #include "nsButtonBoxFrame.h"
     7 #include "nsIContent.h"
     8 #include "nsIDOMNodeList.h"
     9 #include "nsIDOMXULButtonElement.h"
    10 #include "nsGkAtoms.h"
    11 #include "nsNameSpaceManager.h"
    12 #include "nsPresContext.h"
    13 #include "nsIPresShell.h"
    14 #include "nsIDOMElement.h"
    15 #include "nsDisplayList.h"
    16 #include "nsContentUtils.h"
    17 #include "mozilla/dom/Element.h"
    18 #include "mozilla/EventStateManager.h"
    19 #include "mozilla/EventStates.h"
    20 #include "mozilla/MouseEvents.h"
    21 #include "mozilla/TextEvents.h"
    23 using namespace mozilla;
    25 //
    26 // NS_NewXULButtonFrame
    27 //
    28 // Creates a new Button frame and returns it
    29 //
    30 nsIFrame*
    31 NS_NewButtonBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
    32 {
    33   return new (aPresShell) nsButtonBoxFrame(aPresShell, aContext);
    34 }
    36 NS_IMPL_FRAMEARENA_HELPERS(nsButtonBoxFrame)
    38 void
    39 nsButtonBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
    40                                               const nsRect&           aDirtyRect,
    41                                               const nsDisplayListSet& aLists)
    42 {
    43   // override, since we don't want children to get events
    44   if (aBuilder->IsForEventDelivery())
    45     return;
    46   nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
    47 }
    49 nsresult
    50 nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext, 
    51                               WidgetGUIEvent* aEvent,
    52                               nsEventStatus* aEventStatus)
    53 {
    54   NS_ENSURE_ARG_POINTER(aEventStatus);
    55   if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
    56     return NS_OK;
    57   }
    59   switch (aEvent->message) {
    60     case NS_KEY_DOWN: {
    61       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
    62       if (!keyEvent) {
    63         break;
    64       }
    65       if (NS_VK_SPACE == keyEvent->keyCode) {
    66         EventStateManager* esm = aPresContext->EventStateManager();
    67         // :hover:active state
    68         esm->SetContentState(mContent, NS_EVENT_STATE_HOVER);
    69         esm->SetContentState(mContent, NS_EVENT_STATE_ACTIVE);
    70       }
    71       break;
    72     }
    74 // On mac, Return fires the default button, not the focused one.
    75 #ifndef XP_MACOSX
    76     case NS_KEY_PRESS: {
    77       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
    78       if (!keyEvent) {
    79         break;
    80       }
    81       if (NS_VK_RETURN == keyEvent->keyCode) {
    82         nsCOMPtr<nsIDOMXULButtonElement> buttonEl(do_QueryInterface(mContent));
    83         if (buttonEl) {
    84           MouseClicked(aPresContext, aEvent);
    85           *aEventStatus = nsEventStatus_eConsumeNoDefault;
    86         }
    87       }
    88       break;
    89     }
    90 #endif
    92     case NS_KEY_UP: {
    93       WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
    94       if (!keyEvent) {
    95         break;
    96       }
    97       if (NS_VK_SPACE == keyEvent->keyCode) {
    98         // only activate on keyup if we're already in the :hover:active state
    99         NS_ASSERTION(mContent->IsElement(), "How do we have a non-element?");
   100         EventStates buttonState = mContent->AsElement()->State();
   101         if (buttonState.HasAllStates(NS_EVENT_STATE_ACTIVE |
   102                                      NS_EVENT_STATE_HOVER)) {
   103           // return to normal state
   104           EventStateManager* esm = aPresContext->EventStateManager();
   105           esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE);
   106           esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER);
   107           MouseClicked(aPresContext, aEvent);
   108         }
   109       }
   110       break;
   111     }
   113     case NS_MOUSE_CLICK: {
   114       WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   115       if (mouseEvent->IsLeftClickEvent()) {
   116         MouseClicked(aPresContext, mouseEvent);
   117       }
   118       break;
   119     }
   120   }
   122   return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   123 }
   125 void 
   126 nsButtonBoxFrame::DoMouseClick(WidgetGUIEvent* aEvent, bool aTrustEvent)
   127 {
   128   // Don't execute if we're disabled.
   129   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
   130                             nsGkAtoms::_true, eCaseMatters))
   131     return;
   133   // Execute the oncommand event handler.
   134   bool isShift = false;
   135   bool isControl = false;
   136   bool isAlt = false;
   137   bool isMeta = false;
   138   if(aEvent) {
   139     WidgetInputEvent* inputEvent = aEvent->AsInputEvent();
   140     isShift = inputEvent->IsShift();
   141     isControl = inputEvent->IsControl();
   142     isAlt = inputEvent->IsAlt();
   143     isMeta = inputEvent->IsMeta();
   144   }
   146   // Have the content handle the event, propagating it according to normal DOM rules.
   147   nsCOMPtr<nsIPresShell> shell = PresContext()->GetPresShell();
   148   if (shell) {
   149     nsContentUtils::DispatchXULCommand(mContent,
   150                                        aEvent ?
   151                                          aEvent->mFlags.mIsTrusted : aTrustEvent,
   152                                        nullptr, shell,
   153                                        isControl, isAlt, isShift, isMeta);
   154   }
   155 }

mercurial