void MemoryView::MouseDown(BPoint point) { if (!IsFocus()) MakeFocus(true); if (fTargetBlock == NULL) return; int32 buttons; if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK) buttons = B_PRIMARY_MOUSE_BUTTON; if (buttons == B_SECONDARY_MOUSE_BUTTON) { _HandleContextMenu(point); return; } int32 offset = _GetOffsetAt(point); if (offset < fSelectionStart || offset > fSelectionEnd) { BRegion oldSelectionRegion; _GetSelectionRegion(oldSelectionRegion); fSelectionBase = offset; fSelectionStart = fSelectionBase; fSelectionEnd = fSelectionBase; Invalidate(oldSelectionRegion.Frame()); } SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); fTrackingMouse = true; }
void View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region, BRegion* windowContentClipping) { if (!fVisible) return; { // NOTE: use scope in order to reduce stack space requirements // This check will prevent descending the view hierarchy // any further than necessary IntRect screenBounds(Bounds()); ConvertToScreen(&screenBounds); if (!region.Intersects((clipping_rect)screenBounds)) return; // Unfortunately, we intersecting another region, but otherwise // we couldn't provide the exact update rect to the client BRegion localDirty = _ScreenClipping(windowContentClipping); localDirty.IntersectWith(®ion); if (localDirty.CountRects() > 0) { link.Attach<int32>(fToken); link.Attach<BRect>(localDirty.Frame()); } } for (View* child = FirstChild(); child; child = child->NextSibling()) child->AddTokensForViewsInRegion(link, region, windowContentClipping); }
void CCellView::StartDrag(BPoint where, bool copy) { ClearAnts(); BMessage msg(B_SIMPLE_DATA); msg.AddPointer("container", fContainer); msg.AddPointer("cellview", this); msg.AddData("range", 'rang', &fSelection, sizeof(range)); msg.AddBool("dragacopy", copy); BRegion rgn; SelectionToRegion(rgn); cell c; GetCellHitBy(where, c); BRect dragRect = rgn.Frame(); dragRect.OffsetBy(fCellWidths[c.h] - fCellWidths[fSelection.left], fCellHeights[c.v] - fCellHeights[fSelection.top]); BMallocIO buf; CTextConverter conv(buf, fContainer); conv.ConvertToText(&fSelection); msg.AddData("text/plain", B_MIME_DATA, buf.Buffer(), buf.BufferLength()); // and add a nice picture BPicture pic; BRect r; GetPictureOfSelection(&pic, r); pic.Archive(&msg); // msg.AddData("picture", 'PICT', pic.Data(), pic.DataSize()); msg.AddData("rect of pict", 'RECT', &r, sizeof(BRect)); fDragIsAcceptable = true; DragMessage(&msg, dragRect, this); } /* CCellView::StartDrag */
void MyView::DrawSubTree(Layer* lay) { //printf("======== %s =======\n", lay->Name()); // lay->Visible()->PrintToStream(); // lay->FullVisible()->PrintToStream(); for (Layer *child = lay->BottomChild(); child; child = lay->UpperSibling()) DrawSubTree(child); ConstrainClippingRegion(lay->Visible()); SetHighColor(lay->HighColor()); BRegion reg; lay->GetWantedRegion(reg); FillRect(reg.Frame()); Flush(); ConstrainClippingRegion(NULL); }
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color) { if (paintingDisabled()) return; unsigned rectCount = rects.size(); // FIXME: maybe we should implement this with BShape? if (rects.size() > 1) { BRegion region; for (int i = 0; i < rectCount; ++i) region.Include(BRect(rects[i])); m_data->m_view->SetHighColor(color); m_data->m_view->StrokeRect(region.Frame(), B_MIXED_COLORS); } }
status_t PictureDataWriter::WriteSetClipping(const BRegion ®ion) { // TODO: I don't know if it's compatible with R5's BPicture version try { const int32 numRects = region.CountRects(); if (numRects > 0 && region.Frame().IsValid()) { BeginOp(B_PIC_SET_CLIPPING_RECTS); Write<uint32>(numRects); for (int32 i = 0; i < numRects; i++) { Write<BRect>(region.RectAt(i)); } EndOp(); } else WriteClearClipping(); } catch (status_t &status) { return status; } return B_OK; }
void MemoryView::MouseMoved(BPoint point, uint32 transit, const BMessage* message) { if (!fTrackingMouse) return; BRegion oldSelectionRegion; _GetSelectionRegion(oldSelectionRegion); int32 offset = _GetOffsetAt(point); if (offset < fSelectionBase) { fSelectionStart = offset; fSelectionEnd = fSelectionBase; } else { fSelectionStart = fSelectionBase; fSelectionEnd = offset; } BRegion region; _GetSelectionRegion(region); region.Include(&oldSelectionRegion); Invalidate(region.Frame()); switch (transit) { case B_EXITED_VIEW: fScrollRunner = new BMessageRunner(BMessenger(this), new BMessage(MSG_VIEW_AUTOSCROLL), kScrollTimer); break; case B_ENTERED_VIEW: delete fScrollRunner; fScrollRunner = NULL; break; default: break; } }
Layer(Layer* previous) : view(0) , bitmap(0) , clipping() , cippingSet(false) , globalAlpha(255) , currentShape(0) , clipShape(previous->clipShape ? new BShape(*previous->clipShape) : 0) , locationInParent(B_ORIGIN) , accumulatedOrigin(B_ORIGIN) , previous(previous) { BRegion parentClipping; previous->view->GetClippingRegion(&parentClipping); BRect frameInParent = parentClipping.Frame(); if (!frameInParent.IsValid()) frameInParent = previous->view->Bounds(); BRect bounds = frameInParent.OffsetToCopy(B_ORIGIN); locationInParent += frameInParent.LeftTop(); view = new BView(bounds, "WebCore transparency layer", 0, 0); bitmap = new BBitmap(bounds, B_RGBA32, true); bitmap->Lock(); bitmap->AddChild(view); view->SetHighColor(0, 0, 0, 0); view->FillRect(view->Bounds()); view->SetHighColor(previous->view->HighColor()); view->SetDrawingMode(previous->view->DrawingMode()); view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); // TODO: locationInParent and accumulatedOrigin can // probably somehow be merged. But for now it works. accumulatedOrigin.x = -frameInParent.left; accumulatedOrigin.y = -frameInParent.top; view->SetOrigin(previous->accumulatedOrigin + accumulatedOrigin); view->SetScale(previous->view->Scale()); view->SetPenSize(previous->view->PenSize()); }
void View::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, BRegion* windowContentClipping, bool deep) { if (!fVisible) { // child views cannot be visible either return; } if (fViewBitmap != NULL || fViewColor != B_TRANSPARENT_COLOR) { // we can only draw within our own area BRegion* redraw; if ((fFlags & B_DRAW_ON_CHILDREN) != 0) { // The client may actually want to prevent the background to // be painted outside the user clipping. redraw = fWindow->GetRegion( ScreenAndUserClipping(windowContentClipping)); } else { // Ignore user clipping as in BeOS for painting the background. redraw = fWindow->GetRegion( _ScreenClipping(windowContentClipping)); } if (!redraw) return; // add the current clipping redraw->IntersectWith(effectiveClipping); Overlay* overlayCookie = _Overlay(); if (fViewBitmap != NULL && overlayCookie == NULL) { // draw view bitmap // TODO: support other options! BRect rect = fBitmapDestination; ConvertToScreenForDrawing(&rect); align_rect_to_pixels(&rect); if (fBitmapOptions & B_TILE_BITMAP_Y) { // move rect up as much as needed while (rect.top > redraw->Frame().top) rect.OffsetBy(0.0, -(rect.Height() + 1)); } if (fBitmapOptions & B_TILE_BITMAP_X) { // move rect left as much as needed while (rect.left > redraw->Frame().left) rect.OffsetBy(-(rect.Width() + 1), 0.0); } // XXX: locking removed because the Window keeps the engine locked // because it keeps track of syncing right now // lock the drawing engine for as long as we need the clipping // to be valid if (rect.IsValid()/* && drawingEngine->Lock()*/) { drawingEngine->ConstrainClippingRegion(redraw); drawing_mode oldMode; drawingEngine->SetDrawingMode(B_OP_COPY, oldMode); if (fBitmapOptions & B_TILE_BITMAP) { // tile across entire view float start = rect.left; while (rect.top < redraw->Frame().bottom) { while (rect.left < redraw->Frame().right) { drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, rect, fBitmapOptions); rect.OffsetBy(rect.Width() + 1, 0.0); } rect.OffsetBy(start - rect.left, rect.Height() + 1); } // nothing left to be drawn redraw->MakeEmpty(); } else if (fBitmapOptions & B_TILE_BITMAP_X) { // tile in x direction while (rect.left < redraw->Frame().right) { drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, rect, fBitmapOptions); rect.OffsetBy(rect.Width() + 1, 0.0); } // remove horizontal stripe from clipping rect.left = redraw->Frame().left; rect.right = redraw->Frame().right; redraw->Exclude(rect); } else if (fBitmapOptions & B_TILE_BITMAP_Y) { // tile in y direction while (rect.top < redraw->Frame().bottom) { drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, rect, fBitmapOptions); rect.OffsetBy(0.0, rect.Height() + 1); } // remove vertical stripe from clipping rect.top = redraw->Frame().top; rect.bottom = redraw->Frame().bottom; redraw->Exclude(rect); } else { // no tiling at all drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, rect, fBitmapOptions); redraw->Exclude(rect); } drawingEngine->SetDrawingMode(oldMode); // NOTE: It is ok not to reset the clipping, that // would only waste time // drawingEngine->Unlock(); } } if (fViewColor != B_TRANSPARENT_COLOR) { // fill visible region with view color, // this version of FillRegion ignores any // clipping, that's why "redraw" needs to // be correct // see #634 // if (redraw->Frame().left < 0 || redraw->Frame().top < 0) { // char message[1024]; // BRect c = effectiveClipping->Frame(); // BRect w = windowContentClipping->Frame(); // BRect r = redraw->Frame(); // sprintf(message, "invalid background: current clipping: (%d, %d)->(%d, %d), " // "window content: (%d, %d)->(%d, %d), redraw: (%d, %d)->(%d, %d)", // (int)c.left, (int)c.top, (int)c.right, (int)c.bottom, // (int)w.left, (int)w.top, (int)w.right, (int)w.bottom, // (int)r.left, (int)r.top, (int)r.right, (int)r.bottom); // debugger(message); // } drawingEngine->FillRegion(*redraw, overlayCookie != NULL ? overlayCookie->Color() : fViewColor); } fWindow->RecycleRegion(redraw); } fBackgroundDirty = false; // let children draw if (deep) { for (View* child = FirstChild(); child; child = child->NextSibling()) { child->Draw(drawingEngine, effectiveClipping, windowContentClipping, deep); } } }
void View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion) { if (x == 0 && y == 0) return; fFrame.right += x; fFrame.bottom += y; if (fVisible && dirtyRegion) { IntRect oldBounds(Bounds()); oldBounds.right -= x; oldBounds.bottom -= y; BRegion* dirty = fWindow->GetRegion(); if (!dirty) return; dirty->Set((clipping_rect)Bounds()); dirty->Include((clipping_rect)oldBounds); if (!(fFlags & B_FULL_UPDATE_ON_RESIZE)) { // the dirty region is just the difference of // old and new bounds dirty->Exclude((clipping_rect)(oldBounds & Bounds())); } InvalidateScreenClipping(); if (dirty->CountRects() > 0) { if ((fFlags & B_DRAW_ON_CHILDREN) == 0) { // exclude children, they are expected to // include their own dirty regions in ParentResized() for (View* child = FirstChild(); child; child = child->NextSibling()) { if (!child->IsVisible()) continue; IntRect previousChildVisible( child->Frame() & oldBounds & Bounds()); if (dirty->Frame().Intersects(previousChildVisible)) { dirty->Exclude((clipping_rect)previousChildVisible); } } } ConvertToScreen(dirty); dirtyRegion->Include(dirty); } fWindow->RecycleRegion(dirty); } // layout the children for (View* child = FirstChild(); child; child = child->NextSibling()) child->ParentResized(x, y, dirtyRegion); // view bitmap resize_frame(fBitmapDestination, fBitmapResizingMode, x, y); // at this point, children are at their new locations, // so we can rebuild the clipping // TODO: when the implementation of Hide() and Show() is // complete, see if this should be avoided RebuildClipping(false); }