1/*
2 * Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6#include "ViewContainer.h"
7
8#include <Message.h>
9#include <Window.h>
10
11
12// internal messages
13enum {
14	MSG_LAYOUT_CONTAINER			= 'layc',
15};
16
17
18ViewContainer::ViewContainer(BRect frame)
19	: BView(frame, "view container", B_FOLLOW_NONE, B_WILL_DRAW),
20	  View(frame.OffsetToCopy(B_ORIGIN)),
21	  fMouseFocus(NULL)
22{
23	BView::SetViewColor(B_TRANSPARENT_32_BIT);
24	_AddedToContainer(this);
25}
26
27
28void
29ViewContainer::MessageReceived(BMessage* message)
30{
31	switch (message->what) {
32		case MSG_LAYOUT_CONTAINER:
33			View::Layout();
34			break;
35		default:
36			BView::MessageReceived(message);
37			break;
38	}
39}
40
41
42void
43ViewContainer::AllAttached()
44{
45	Window()->PostMessage(MSG_LAYOUT_CONTAINER, this);
46}
47
48
49void
50ViewContainer::Draw(BRect updateRect)
51{
52	View::_Draw(this, updateRect);
53}
54
55
56void
57ViewContainer::MouseDown(BPoint where)
58{
59	// get mouse buttons and modifiers
60	uint32 buttons;
61	int32 modifiers;
62	_GetButtonsAndModifiers(buttons, modifiers);
63
64	// get mouse focus
65	if (!fMouseFocus && (buttons & B_PRIMARY_MOUSE_BUTTON)) {
66		fMouseFocus = AncestorAt(where);
67		if (fMouseFocus)
68			SetMouseEventMask(B_POINTER_EVENTS);
69	}
70
71	// call hook
72	if (fMouseFocus) {
73		fMouseFocus->MouseDown(fMouseFocus->ConvertFromContainer(where),
74			buttons, modifiers);
75	}
76}
77
78
79void
80ViewContainer::MouseUp(BPoint where)
81{
82	if (!fMouseFocus)
83		return;
84
85	// get mouse buttons and modifiers
86	uint32 buttons;
87	int32 modifiers;
88	_GetButtonsAndModifiers(buttons, modifiers);
89
90	// call hook
91	if (fMouseFocus) {
92		fMouseFocus->MouseUp(fMouseFocus->ConvertFromContainer(where),
93			buttons, modifiers);
94	}
95
96	// unset the mouse focus when the primary button has been released
97	if (!(buttons & B_PRIMARY_MOUSE_BUTTON))
98		fMouseFocus = NULL;
99}
100
101
102void
103ViewContainer::MouseMoved(BPoint where, uint32 code, const BMessage* message)
104{
105	if (!fMouseFocus)
106		return;
107
108	// get mouse buttons and modifiers
109	uint32 buttons;
110	int32 modifiers;
111	_GetButtonsAndModifiers(buttons, modifiers);
112
113	// call hook
114	if (fMouseFocus) {
115		fMouseFocus->MouseMoved(fMouseFocus->ConvertFromContainer(where),
116			buttons, modifiers);
117	}
118}
119
120
121void
122ViewContainer::InvalidateLayout(bool descendants)
123{
124	BView::InvalidateLayout(descendants);
125}
126
127
128void
129ViewContainer::InvalidateLayout()
130{
131	if (View::IsLayoutValid()) {
132		View::InvalidateLayout();
133
134		// trigger asynchronous re-layout
135		if (Window())
136			Window()->PostMessage(MSG_LAYOUT_CONTAINER, this);
137	}
138}
139
140
141void
142ViewContainer::Draw(BView* container, BRect updateRect)
143{
144}
145
146
147void
148ViewContainer::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
149{
150}
151
152
153void
154ViewContainer::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
155{
156}
157
158
159void
160ViewContainer::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
161{
162}
163
164
165void
166ViewContainer::_GetButtonsAndModifiers(uint32& buttons, int32& modifiers)
167{
168	buttons = 0;
169	modifiers = 0;
170
171	if (BMessage* message = Window()->CurrentMessage()) {
172		if (message->FindInt32("buttons", (int32*)&buttons) != B_OK)
173			buttons = 0;
174		if (message->FindInt32("modifiers", modifiers) != B_OK)
175			modifiers = 0;
176	}
177}
178