Example #1
0
// Find all windows containing a given point (x, y) and interested in at least
// one of the input evens in wantedInputMask. We have to traverse all windows
// because children are not guaranteed to be bounded by their parent.
// It's very likely to return more than one window because our window hierarchy
// is a tree. Because we traverse the tree breadth-first, parent windows will be
// in windows array before child windows. In most cases caller can use the last
// window in returned array (but can use a custom logic as well).
// Returns number of matched windows as a convenience.
size_t CollectWindowsAt(Control *wndRoot, int x, int y, uint16 wantedInputMask, Vec<CtrlAndOffset> *controls)
{
    WndInputWantedFilter filter(x, y, wantedInputMask);
    controls->Reset();
    CollectWindowsBreathFirst(wndRoot, 0, 0, &filter, controls);
    return controls->Count();
}
// Paint windows in z-order by first collecting the windows
// and then painting consecutive layers with the same z-order,
// starting with the lowest z-order.
// We don't sort because we want to preserve the order of
// containment of windows with the same z-order and non-stable
// sort could change it.
static void PaintWindowsInZOrder(Graphics *g, Control *c)
{
    Vec<CtrlAndOffset>  toPaint;
    WndFilter           wndFilter;
    CtrlAndOffset *     coff;
    Pen                 debugPen(Color(255, 0, 0), 1);

    CollectWindowsBreathFirst(c, 0, 0, &wndFilter, &toPaint);
    size_t paintedCount = 0;
    int16 lastPaintedZOrder = INT16_MIN;
    for (;;) {
        // find which z-order should we paint now
        int16 minUnpaintedZOrder = INT16_MAX;
        for (coff = toPaint.IterStart(); coff; coff = toPaint.IterNext()) {
            int16 zOrder = coff->c->zOrder;
            if ((zOrder > lastPaintedZOrder) && (zOrder < minUnpaintedZOrder))
                minUnpaintedZOrder = zOrder;
        }
        for (coff = toPaint.IterStart(); coff; coff = toPaint.IterNext()) {
            if (minUnpaintedZOrder == coff->c->zOrder) {
                coff->c->Paint(g, coff->offX, coff->offY);
                if (IsDebugPaint()) {
                    Rect bbox(coff->offX, coff->offY, coff->c->pos.Width, coff->c->pos.Height);
                    g->DrawRectangle(&debugPen, bbox);
                }
                ++paintedCount;
            }
        }
        if (paintedCount == toPaint.Count())
            return;
        CrashIf(paintedCount > toPaint.Count());
        lastPaintedZOrder = minUnpaintedZOrder;
    }
}
Example #3
0
void CollectWindowsBreathFirst(Control *c, int offX, int offY, WndFilter *wndFilter, Vec<CtrlAndOffset> *ctrls)
{
    if (wndFilter->skipInvisibleSubtrees && !c->IsVisible())
        return;

    offX += c->pos.X;
    offY += c->pos.Y;
    if (wndFilter->Matches(c, offX, offY)) {
        CtrlAndOffset coff = { c, offX, offY };
        ctrls->Append(coff);
    }

    size_t children = c->GetChildCount();
    for (size_t i = 0; i < children; i++) {
        CollectWindowsBreathFirst(c->GetChild(i), offX, offY, wndFilter, ctrls);
    }
}