layout/xul/nsTitleBarFrame.cpp

branch
TOR_BUG_9701
changeset 11
deefc01c0e14
equal deleted inserted replaced
-1:000000000000 0:fdf93a5eefc9
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
6 #include "nsCOMPtr.h"
7 #include "nsTitleBarFrame.h"
8 #include "nsIContent.h"
9 #include "nsIDocument.h"
10 #include "nsIDOMNodeList.h"
11 #include "nsGkAtoms.h"
12 #include "nsIWidget.h"
13 #include "nsMenuPopupFrame.h"
14 #include "nsPresContext.h"
15 #include "nsIDocShell.h"
16 #include "nsPIDOMWindow.h"
17 #include "nsDisplayList.h"
18 #include "nsContentUtils.h"
19 #include "mozilla/MouseEvents.h"
20
21 using namespace mozilla;
22
23 //
24 // NS_NewTitleBarFrame
25 //
26 // Creates a new TitleBar frame and returns it
27 //
28 nsIFrame*
29 NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
30 {
31 return new (aPresShell) nsTitleBarFrame(aPresShell, aContext);
32 }
33
34 NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame)
35
36 nsTitleBarFrame::nsTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
37 :nsBoxFrame(aPresShell, aContext, false)
38 {
39 mTrackingMouseMove = false;
40 UpdateMouseThrough();
41 }
42
43 void
44 nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
45 const nsRect& aDirtyRect,
46 const nsDisplayListSet& aLists)
47 {
48 // override, since we don't want children to get events
49 if (aBuilder->IsForEventDelivery()) {
50 if (!mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
51 nsGkAtoms::_true, eCaseMatters))
52 return;
53 }
54 nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
55 }
56
57 nsresult
58 nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext,
59 WidgetGUIEvent* aEvent,
60 nsEventStatus* aEventStatus)
61 {
62 NS_ENSURE_ARG_POINTER(aEventStatus);
63 if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
64 return NS_OK;
65 }
66
67 bool doDefault = true;
68
69 switch (aEvent->message) {
70
71 case NS_MOUSE_BUTTON_DOWN: {
72 if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
73 // titlebar has no effect in non-chrome shells
74 nsCOMPtr<nsIDocShellTreeItem> dsti = aPresContext->GetDocShell();
75 if (dsti) {
76 if (dsti->ItemType() == nsIDocShellTreeItem::typeChrome) {
77 // we're tracking.
78 mTrackingMouseMove = true;
79
80 // start capture.
81 nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
82
83 // remember current mouse coordinates.
84 mLastPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint);
85 }
86 }
87
88 *aEventStatus = nsEventStatus_eConsumeNoDefault;
89 doDefault = false;
90 }
91 }
92 break;
93
94
95 case NS_MOUSE_BUTTON_UP: {
96 if (mTrackingMouseMove &&
97 aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
98 // we're done tracking.
99 mTrackingMouseMove = false;
100
101 // end capture
102 nsIPresShell::SetCapturingContent(nullptr, 0);
103
104 *aEventStatus = nsEventStatus_eConsumeNoDefault;
105 doDefault = false;
106 }
107 }
108 break;
109
110 case NS_MOUSE_MOVE: {
111 if(mTrackingMouseMove)
112 {
113 nsIntPoint nsMoveBy = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) - mLastPoint;
114
115 nsIFrame* parent = GetParent();
116 while (parent) {
117 nsMenuPopupFrame* popupFrame = do_QueryFrame(parent);
118 if (popupFrame)
119 break;
120 parent = parent->GetParent();
121 }
122
123 // if the titlebar is in a popup, move the popup frame, otherwise
124 // move the widget associated with the window
125 if (parent) {
126 nsMenuPopupFrame* menuPopupFrame = static_cast<nsMenuPopupFrame*>(parent);
127 nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget();
128 nsIntRect bounds;
129 widget->GetScreenBounds(bounds);
130
131 int32_t newx = aPresContext->DevPixelsToIntCSSPixels(bounds.x + nsMoveBy.x);
132 int32_t newy = aPresContext->DevPixelsToIntCSSPixels(bounds.y + nsMoveBy.y);
133 menuPopupFrame->MoveTo(newx, newy, false);
134 }
135 else {
136 nsIPresShell* presShell = aPresContext->PresShell();
137 nsPIDOMWindow *window = presShell->GetDocument()->GetWindow();
138 if (window) {
139 window->MoveBy(nsMoveBy.x, nsMoveBy.y);
140 }
141 }
142
143 *aEventStatus = nsEventStatus_eConsumeNoDefault;
144
145 doDefault = false;
146 }
147 }
148 break;
149
150 case NS_MOUSE_CLICK: {
151 WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
152 if (mouseEvent->IsLeftClickEvent()) {
153 MouseClicked(aPresContext, mouseEvent);
154 }
155 break;
156 }
157 }
158
159 if ( doDefault )
160 return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
161 else
162 return NS_OK;
163 }
164
165 void
166 nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext,
167 WidgetMouseEvent* aEvent)
168 {
169 // Execute the oncommand event handler.
170 nsContentUtils::DispatchXULCommand(mContent,
171 aEvent && aEvent->mFlags.mIsTrusted);
172 }

mercurial