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 13 enum { 14 MSG_LAYOUT_CONTAINER = 'layc', 15 }; 16 17 18 ViewContainer::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 28 void 29 ViewContainer::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 42 void 43 ViewContainer::AllAttached() 44 { 45 Window()->PostMessage(MSG_LAYOUT_CONTAINER, this); 46 } 47 48 49 void 50 ViewContainer::Draw(BRect updateRect) 51 { 52 View::_Draw(this, updateRect); 53 } 54 55 56 void 57 ViewContainer::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 79 void 80 ViewContainer::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 102 void 103 ViewContainer::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 121 void 122 ViewContainer::InvalidateLayout(bool descendants) 123 { 124 BView::InvalidateLayout(descendants); 125 } 126 127 128 void 129 ViewContainer::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 141 void 142 ViewContainer::Draw(BView* container, BRect updateRect) 143 { 144 } 145 146 147 void 148 ViewContainer::MouseDown(BPoint where, uint32 buttons, int32 modifiers) 149 { 150 } 151 152 153 void 154 ViewContainer::MouseUp(BPoint where, uint32 buttons, int32 modifiers) 155 { 156 } 157 158 159 void 160 ViewContainer::MouseMoved(BPoint where, uint32 buttons, int32 modifiers) 161 { 162 } 163 164 165 void 166 ViewContainer::_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