1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Original Author: Eric J. Burley (ericb@neoplanet.com)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsCOMPtr.h"
40 : #include "nsTitleBarFrame.h"
41 : #include "nsIContent.h"
42 : #include "nsIDocument.h"
43 : #include "nsIDOMXULDocument.h"
44 : #include "nsIDOMNodeList.h"
45 : #include "nsGkAtoms.h"
46 : #include "nsIWidget.h"
47 : #include "nsMenuPopupFrame.h"
48 : #include "nsPresContext.h"
49 : #include "nsIDocShellTreeItem.h"
50 : #include "nsPIDOMWindow.h"
51 : #include "nsGUIEvent.h"
52 : #include "nsEventDispatcher.h"
53 : #include "nsDisplayList.h"
54 : #include "nsContentUtils.h"
55 :
56 : //
57 : // NS_NewTitleBarFrame
58 : //
59 : // Creates a new TitleBar frame and returns it
60 : //
61 : nsIFrame*
62 0 : NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
63 : {
64 0 : return new (aPresShell) nsTitleBarFrame(aPresShell, aContext);
65 : }
66 :
67 0 : NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame)
68 :
69 0 : nsTitleBarFrame::nsTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
70 0 : :nsBoxFrame(aPresShell, aContext, false)
71 : {
72 0 : mTrackingMouseMove = false;
73 0 : UpdateMouseThrough();
74 0 : }
75 :
76 : NS_IMETHODIMP
77 0 : nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
78 : const nsRect& aDirtyRect,
79 : const nsDisplayListSet& aLists)
80 : {
81 : // override, since we don't want children to get events
82 0 : if (aBuilder->IsForEventDelivery()) {
83 0 : if (!mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
84 0 : nsGkAtoms::_true, eCaseMatters))
85 0 : return NS_OK;
86 : }
87 0 : return nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
88 : }
89 :
90 : NS_IMETHODIMP
91 0 : nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext,
92 : nsGUIEvent* aEvent,
93 : nsEventStatus* aEventStatus)
94 : {
95 0 : NS_ENSURE_ARG_POINTER(aEventStatus);
96 0 : if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
97 0 : return NS_OK;
98 : }
99 :
100 0 : bool doDefault = true;
101 :
102 0 : switch (aEvent->message) {
103 :
104 : case NS_MOUSE_BUTTON_DOWN: {
105 0 : if (aEvent->eventStructType == NS_MOUSE_EVENT &&
106 : static_cast<nsMouseEvent*>(aEvent)->button ==
107 : nsMouseEvent::eLeftButton)
108 : {
109 : // titlebar has no effect in non-chrome shells
110 0 : nsCOMPtr<nsISupports> cont = aPresContext->GetContainer();
111 0 : nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont);
112 0 : if (dsti) {
113 0 : PRInt32 type = -1;
114 0 : if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
115 : type == nsIDocShellTreeItem::typeChrome) {
116 : // we're tracking.
117 0 : mTrackingMouseMove = true;
118 :
119 : // start capture.
120 0 : nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
121 :
122 : // remember current mouse coordinates.
123 0 : mLastPoint = aEvent->refPoint;
124 : }
125 : }
126 :
127 0 : *aEventStatus = nsEventStatus_eConsumeNoDefault;
128 0 : doDefault = false;
129 : }
130 : }
131 0 : break;
132 :
133 :
134 : case NS_MOUSE_BUTTON_UP: {
135 0 : if(mTrackingMouseMove && aEvent->eventStructType == NS_MOUSE_EVENT &&
136 : static_cast<nsMouseEvent*>(aEvent)->button ==
137 : nsMouseEvent::eLeftButton)
138 : {
139 : // we're done tracking.
140 0 : mTrackingMouseMove = false;
141 :
142 : // end capture
143 0 : nsIPresShell::SetCapturingContent(nsnull, 0);
144 :
145 0 : *aEventStatus = nsEventStatus_eConsumeNoDefault;
146 0 : doDefault = false;
147 : }
148 : }
149 0 : break;
150 :
151 : case NS_MOUSE_MOVE: {
152 0 : if(mTrackingMouseMove)
153 : {
154 0 : nsIntPoint nsMoveBy = aEvent->refPoint - mLastPoint;
155 :
156 0 : nsIFrame* parent = GetParent();
157 0 : while (parent && parent->GetType() != nsGkAtoms::menuPopupFrame)
158 0 : parent = parent->GetParent();
159 :
160 : // if the titlebar is in a popup, move the popup frame, otherwise
161 : // move the widget associated with the window
162 0 : if (parent) {
163 0 : nsMenuPopupFrame* menuPopupFrame = static_cast<nsMenuPopupFrame*>(parent);
164 0 : nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget();
165 0 : nsIntRect bounds;
166 0 : widget->GetScreenBounds(bounds);
167 0 : menuPopupFrame->MoveTo(bounds.x + nsMoveBy.x, bounds.y + nsMoveBy.y, false);
168 : }
169 : else {
170 0 : nsIPresShell* presShell = aPresContext->PresShell();
171 0 : nsPIDOMWindow *window = presShell->GetDocument()->GetWindow();
172 0 : if (window) {
173 0 : window->MoveBy(nsMoveBy.x, nsMoveBy.y);
174 : }
175 : }
176 :
177 0 : *aEventStatus = nsEventStatus_eConsumeNoDefault;
178 :
179 0 : doDefault = false;
180 : }
181 : }
182 0 : break;
183 :
184 :
185 :
186 : case NS_MOUSE_CLICK:
187 0 : if (NS_IS_MOUSE_LEFT_CLICK(aEvent))
188 : {
189 0 : MouseClicked(aPresContext, aEvent);
190 : }
191 0 : break;
192 : }
193 :
194 0 : if ( doDefault )
195 0 : return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
196 : else
197 0 : return NS_OK;
198 : }
199 :
200 : void
201 0 : nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent)
202 : {
203 : // Execute the oncommand event handler.
204 : nsContentUtils::DispatchXULCommand(mContent,
205 : aEvent ?
206 0 : NS_IS_TRUSTED_EVENT(aEvent) : false);
207 0 : }
|