17 node(const BRect
& r
, int32 maxPointers
)
26 void init(const BRect
& r
, int32 maxPointers
)
29 pointers
= new node
*[maxPointers
];
36 pointers
[next_pointer
] = node
;
41 return pointers
[next_pointer
];
57 is_left_of(const BRect
& a
, const BRect
& b
)
59 return (a
.right
< b
.left
);
62 is_above(const BRect
& a
, const BRect
& b
)
64 return (a
.bottom
< b
.top
);
67 MyView::MyView(BRect frame
, const char *name
, uint32 resizingMode
, uint32 flags
)
68 : BView(frame
, name
, resizingMode
, flags
)
70 SetViewColor(B_TRANSPARENT_COLOR
);
80 topLayer
= new Layer(Bounds(), "topLayer", B_FOLLOW_ALL
, 0, col
);
81 topLayer
->SetRootLayer(this);
83 topLayer
->rebuild_visible_regions(BRegion(Bounds()), BRegion(Bounds()), NULL
);
84 fRedrawReg
.Set(Bounds());
92 Layer
* MyView::FindLayer(Layer
*lay
, BPoint
&where
) const
94 if (lay
->Visible()->Contains(where
))
97 for (Layer
*child
= lay
->BottomChild(); child
; child
= lay
->UpperSibling())
99 Layer
*found
= FindLayer(child
, where
);
106 void MyView::MouseDown(BPoint where
)
108 SetMouseEventMask(B_POINTER_EVENTS
, B_LOCK_WINDOW_FOCUS
);
110 Looper()->CurrentMessage()->FindInt32("buttons", &buttons
);
112 if (buttons
== B_PRIMARY_MOUSE_BUTTON
)
115 fMovingLayer
= FindLayer(topLayer
, where
);
116 if (fMovingLayer
== topLayer
)
120 BRect
bounds(fMovingLayer
->Bounds());
121 fMovingLayer
->ConvertToScreen2(&bounds
);
122 BRect
resizeRect(bounds
.right
-10, bounds
.bottom
-10, bounds
.right
, bounds
.bottom
);
123 if (resizeRect
.Contains(where
))
129 else if (buttons
== B_SECONDARY_MOUSE_BUTTON
)
133 else if (buttons
== B_TERTIARY_MOUSE_BUTTON
)
135 DrawSubTree(topLayer
);
139 void MyView::MouseUp(BPoint where
)
142 fIs2ndButton
= false;
146 void MyView::MouseMoved(BPoint where
, uint32 code
, const BMessage
*a_message
)
151 dx
= where
.x
- fLastPos
.x
;
152 dy
= where
.y
- fLastPos
.y
;
155 if (dx
!= 0 || dy
!= 0)
159 bigtime_t now
= system_time();
161 fMovingLayer
->ResizeBy(dx
, dy
);
162 printf("resizing: %lld\n", system_time() - now
);
164 fMovingLayer
->MoveBy(dx
, dy
);
165 printf("moving: %lld\n", system_time() - now
);
170 else if (fIs2ndButton
)
173 StrokeLine(fLastPos
, where
);
179 void MyView::MessageReceived(BMessage
*msg
)
183 case B_MOUSE_WHEEL_CHANGED
:
186 msg
->FindFloat("be:wheel_delta_y", &dy
);
191 GetMouse(&pt
, &buttons
, false);
192 if ((lay
= FindLayer(topLayer
, pt
)))
193 lay
->ScrollBy(0, dy
*5);
197 BView::MessageReceived(msg
);
201 void MyView::CopyRegion(BRegion
*region
, int32 xOffset
, int32 yOffset
)
204 int32 count
= region
->CountRects();
206 // TODO: make this step unnecessary
207 // (by using different stack impl inside node)
209 for (int32 i
= 0; i
< count
; i
++) {
210 nodes
[i
].init(region
->RectAt(i
), count
);
213 for (int32 i
= 0; i
< count
; i
++) {
214 BRect a
= region
->RectAt(i
);
215 for (int32 k
= i
+ 1; k
< count
; k
++) {
216 BRect b
= region
->RectAt(k
);
218 // compare horizontally
220 if (is_left_of(a
, b
)) {
222 } else if (is_left_of(b
, a
)) {
225 } else if (xOffset
< 0) {
226 if (is_left_of(a
, b
)) {
228 } else if (is_left_of(b
, a
)) {
232 // compare vertically
234 if (is_above(a
, b
)) {
236 } else if (is_above(b
, a
)) {
239 } else if (yOffset
< 0) {
240 if (is_above(a
, b
)) {
242 } else if (is_above(b
, a
)) {
246 // add appropriate node as successor
248 nodes
[i
].push(&nodes
[k
]);
249 nodes
[k
].in_degree
++;
250 } else if (cmp
< 0) {
251 nodes
[k
].push(&nodes
[i
]);
252 nodes
[i
].in_degree
++;
256 // put all nodes onto a stack that have an "indegree" count of zero
257 stack
<node
*> inDegreeZeroNodes
;
258 for (int32 i
= 0; i
< count
; i
++) {
259 if (nodes
[i
].in_degree
== 0) {
260 inDegreeZeroNodes
.push(&nodes
[i
]);
263 // pop the rects from the stack, do the actual copy operation
264 // and decrease the "indegree" count of the other rects not
265 // currently on the stack and to which the current rect pointed
266 // to. If their "indegree" count reaches zero, put them onto the
269 while (!inDegreeZeroNodes
.empty()) {
270 node
* n
= inDegreeZeroNodes
.top();
271 inDegreeZeroNodes
.pop();
273 CopyBits(n
->rect
, BRect(n
->rect
).OffsetByCopy(xOffset
, yOffset
));
275 for (int32 k
= 0; k
< n
->next_pointer
; k
++) {
276 n
->pointers
[k
]->in_degree
--;
277 if (n
->pointers
[k
]->in_degree
== 0)
278 inDegreeZeroNodes
.push(n
->pointers
[k
]);
284 void MyView::RequestRedraw()
288 ConstrainClippingRegion(&fRedrawReg
);
290 DrawSubTree(topLayer
);
292 ConstrainClippingRegion(NULL
);
294 fRedrawReg
.MakeEmpty();
299 void MyView::Draw(BRect area
)
301 // empty. you can trigger a redraw by clicking the middle mouse button.
304 void MyView::DrawSubTree(Layer
* lay
)
306 //printf("======== %s =======\n", lay->Name());
307 // lay->Visible()->PrintToStream();
308 // lay->FullVisible()->PrintToStream();
309 for (Layer
*child
= lay
->BottomChild(); child
; child
= lay
->UpperSibling())
312 ConstrainClippingRegion(lay
->Visible());
313 SetHighColor(lay
->HighColor());
315 lay
->GetWantedRegion(reg
);
316 FillRect(reg
.Frame());
318 ConstrainClippingRegion(NULL
);