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.

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

mercurial