void APListItemDescription::DrawItemColumn(BView *owner, BRect itemColumnRect, int32 columnIndex, bool complete) { BRegion region; char *strPtr; // Initialize drawing owner->SetLowColor(White); owner->SetDrawingMode(B_OP_COPY); // Draw the background color if (complete) { owner->SetHighColor(White); owner->FillRect(itemColumnRect); } // Draw the item region.Include(itemColumnRect); owner->ConstrainClippingRegion(®ion); owner->SetHighColor(Black); owner->DrawString((strPtr = columnText.GetString()), BPoint(itemColumnRect.left + 2.0f, itemColumnRect.top + textOffset)); columnText.FreeBuffer(strPtr); owner->ConstrainClippingRegion(NULL); }
BView *BubbleHelper::FindView(BPoint where) { BView *winview=NULL; BWindow *win; long windex=0; while((winview==NULL)&&((win=be_app->WindowAt(windex++))!=NULL)) { if(win!=textwin) { // lock with timeout, in case somebody has a non-running window around // in their app. if(win->LockWithTimeout(1E6)==B_OK) { BRect frame=win->Frame(); if(frame.Contains(where)) { BPoint winpoint; winpoint=where-frame.LeftTop(); winview=win->FindView(winpoint); if(winview) { BRegion region; BPoint newpoint=where; winview->ConvertFromScreen(&newpoint); winview->GetClippingRegion(®ion); if(!region.Contains(newpoint)) winview=0; } } win->Unlock(); } } } return winview; }
virtual void Draw(BRect updateRect) { BRegion region; region.Include(BRect(20, 20, 40, 40)); region.Include(BRect(30, 30, 80, 80)); ConstrainClippingRegion(®ion); SetHighColor(55, 255, 128, 255); FillRect(BRect(0, 0, 100, 100)); PushState(); SetOrigin(15, 15); ConstrainClippingRegion(®ion); SetHighColor(155, 255, 128, 255); FillRect(BRect(0, 0, 100, 100)); // ConstrainClippingRegion(NULL); SetHighColor(0, 0, 0, 255); StrokeLine(BPoint(2, 2), BPoint(80, 80)); SetHighColor(255, 0, 0, 255); StrokeLine(BPoint(2, 2), BPoint(4, 2)); PopState(); SetHighColor(0, 0, 0, 255); StrokeLine(BPoint(4, 2), BPoint(82, 80)); }
void ObjectView::Draw(BRect region) { BRect bnd = Bounds(); BRegion regi; regi.Include(region); ConstrainClippingRegion(®i); if (isSelected) { SetDrawingMode(B_OP_OVER); SetHighColor(black); FillRect(bnd, B_SOLID_HIGH); SetViewColor(black); SetHighColor(color); } else { SetDrawingMode(B_OP_OVER); SetHighColor(color); FillRect(bnd, B_SOLID_HIGH); SetViewColor(color); SetHighColor(black); } StrokeRect(bnd, B_SOLID_HIGH); if (label) { DrawString(label, labelPoint); if (container) { BRect cb = container->Bounds(); int d = (cb.right-cb.left-30); int llbl; for ( llbl = labelPoint.x + (1+(((int32)region.left) / d)) * d; llbl < region.right; llbl += d) { DrawString(label, BPoint(llbl,labelPoint.y)); } } } }
void SimpleTransformTest::TransformRegion() { BRegion region; region.Include(BRect( 5.0, 5.0, 20.0, 20.0)); region.Include(BRect(10.0, 10.0, 30.0, 30.0)); region.Exclude(BRect(10.0, 20.0, 20.0, 25.0)); BRegion reference1 = region; reference1.OffsetBy(10, 20); SimpleTransform specimen; specimen.AddOffset(10.0, 20.0); specimen.Apply(®ion); CPPUNIT_ASSERT(region == reference1); specimen.SetScale(2.5); BRegion reference2; reference2.Include(BRect(47.0, 82.0, 87.0, 122.0)); reference2.Include(BRect(60.0, 95.0, 112.0, 147.0)); reference2.Exclude(BRect(60.0, 120.0, 86.0, 134.0)); specimen.Apply(®ion); CPPUNIT_ASSERT(region == reference2); }
void CLVListItem::DrawItem(BView* owner, BRect itemRect, bool complete) { BList* DisplayList = &((ColumnListView*)owner)->fColumnDisplayList; int32 NumberOfColumns = DisplayList->CountItems(); //float PushMax = itemRect.right; CLVColumn* ThisColumn; BRect ThisColumnRect = itemRect; BRegion ClippingRegion; if(!complete) owner->GetClippingRegion(&ClippingRegion); else ClippingRegion.Set(itemRect); float LastColumnEnd = -1.0; //Draw the columns for(int32 Counter = 0; Counter < NumberOfColumns; Counter++) { ThisColumn = (CLVColumn*)DisplayList->ItemAt(Counter); if(!ThisColumn->IsShown()) continue; ThisColumnRect.left = ThisColumn->fColumnBegin; ThisColumnRect.right = LastColumnEnd = ThisColumn->fColumnEnd; if(ThisColumnRect.right >= ThisColumnRect.left && ClippingRegion.Intersects(ThisColumnRect)) DrawItemColumn(owner, ThisColumnRect, ((ColumnListView*)owner)->fColumnList.IndexOf(ThisColumn),complete); } //Fill the area after all the columns (so the select highlight goes all the way across) ThisColumnRect.left = LastColumnEnd + 1.0; ThisColumnRect.right = owner->Bounds().right; if(ThisColumnRect.left <= ThisColumnRect.right && ClippingRegion.Intersects(ThisColumnRect)) DrawItemColumn(owner, ThisColumnRect,-1,complete); }
void DrawState::Transform(BRegion* region) const { if (fCombinedScale == 1.0) { region->OffsetBy(fCombinedOrigin.x, fCombinedOrigin.y); } else { // TODO: optimize some more BRegion converted; int32 count = region->CountRects(); for (int32 i = 0; i < count; i++) { BRect r = region->RectAt(i); BPoint lt(r.LeftTop()); BPoint rb(r.RightBottom()); // offset to bottom right corner of pixel before transformation rb.x++; rb.y++; // apply transformation Transform(<.x, <.y); Transform(&rb.x, &rb.y); // reset bottom right to pixel "index" rb.x--; rb.y--; // add rect to converted region // NOTE/TODO: the rect would not have to go // through the whole intersection test process, // it is guaranteed not to overlap with any rect // already contained in the region converted.Include(BRect(lt, rb)); } *region = converted; } }
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::SetHidden(bool hidden) { if (fHidden != hidden) { fHidden = hidden; // recurse into children and update their visible flag bool oldVisible = fVisible; UpdateVisibleDeep(fParent ? fParent->IsVisible() : !fHidden); if (oldVisible != fVisible) { // Include or exclude us from the parent area, and update the // children's clipping as well when the view will be visible if (fParent) fParent->RebuildClipping(fVisible); else RebuildClipping(fVisible); if (fWindow) { // trigger a redraw IntRect clippedBounds = Bounds(); ConvertToVisibleInTopView(&clippedBounds); BRegion* dirty = fWindow->GetRegion(); if (!dirty) return; dirty->Set((clipping_rect)clippedBounds); fWindow->MarkContentDirty(*dirty); fWindow->RecycleRegion(dirty); } } } }
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 RemoteFileItem::DrawItemColumn(BView * clv, BRect itemRect, int32 colIdx, bool complete) { bool selected = IsSelected(); rgb_color color = (selected) ? ((ColumnListView*)clv)->ItemSelectColor() : _owner->GetShareWindow()->GetColor(COLOR_BG); clv->SetLowColor(color); if ((selected) || (complete)) { clv->SetHighColor(color); clv->FillRect(itemRect); } if (colIdx > 0) { BRegion Region; Region.Include(itemRect); clv->ConstrainClippingRegion(&Region); clv->SetHighColor(_owner->GetShareWindow()->GetColor(COLOR_TEXT)); const char* text = _owner->GetShareWindow()->GetFileCellText(this, colIdx); if (text) clv->DrawString(text, BPoint(itemRect.left+2.0,itemRect.top+_textOffset)); clv->ConstrainClippingRegion(NULL); } else if (colIdx == 0) { const BBitmap* bmp = _owner->GetShareWindow()->GetBitmap(this, colIdx); if (bmp) { clv->SetDrawingMode(B_OP_OVER); clv->DrawBitmap(bmp, BPoint(itemRect.left + ((itemRect.Width()-bmp->Bounds().Width())/2.0f), itemRect.top+((itemRect.Height()-bmp->Bounds().Height())/2.0f))); } } }
void TStageMovieCue::UpdatePictureCueRegion(double theTime) { // Determine channelID int32 cueChannelID = m_ChannelCue->GetChannelID(); // Get total channels int32 totalChannels = static_cast<MuseumApp *>(be_app)->GetCueSheet()->GetCueSheetView()->GetTotalChannels(); // Determine cue layer. Iterate through all higher layers and determine // the area to be invalidated. Construct a region to do this. Exlude all // other area rects in higher channels than us. We wil then break // the region down into rects and invalidate them. BRegion invalRegion; invalRegion.Include(m_ChannelCue->GetArea()); for(int32 index = cueChannelID+1; index <= totalChannels; index++) { TStageCue *stageCue = ((TStageView *)Parent())->GetStageCueAtTimeandChannel(theTime, index); if (stageCue) invalRegion.Exclude( stageCue->GetChannelCue()->GetArea()); } // Now call our custom invalidation routine for(int32 index = 0; index < invalRegion.CountRects(); index++) { Parent()->Invalidate( invalRegion.RectAt(index)); //((TStageView *)Parent())->StageDraw( invalRegion.RectAt(index), theTime); } }
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 */
static cairo_int_status_t _cairo_beos_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { fprintf(stderr, "Setting clip region\n"); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; if (region == NULL) { // No clipping surface->view->ConstrainClippingRegion(NULL); return CAIRO_INT_STATUS_SUCCESS; } int count = pixman_region_num_rects(region); pixman_box16_t* rects = pixman_region_rects(region); BRegion bregion; for (int i = 0; i < count; ++i) { // Have to substract one, because for pixman, the second coordinate // lies outside the rectangle. bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2 - 1)); } surface->view->ConstrainClippingRegion(&bregion); return CAIRO_INT_STATUS_SUCCESS; }
BRegion& View::_ScreenClipping(BRegion* windowContentClipping, bool force) const { if (!fScreenClippingValid || force) { fScreenClipping = fLocalClipping; ConvertToScreen(&fScreenClipping); // see if parts of our bounds are hidden underneath // the parent, the local clipping does not account for this IntRect clippedBounds = Bounds(); ConvertToVisibleInTopView(&clippedBounds); if (clippedBounds.Width() < fScreenClipping.Frame().Width() || clippedBounds.Height() < fScreenClipping.Frame().Height()) { BRegion* temp = fWindow->GetRegion(); if (temp) { temp->Set((clipping_rect)clippedBounds); fScreenClipping.IntersectWith(temp); fWindow->RecycleRegion(temp); } } fScreenClipping.IntersectWith(windowContentClipping); fScreenClippingValid = true; } return fScreenClipping; }
virtual void MessageReceived(BMessage* message) { switch (message->what) { case MSG_REDRAW: { #if TEST_DELAYS if (fDelay) { snooze(200000); fDelay = false; } #endif BRegion region; BRect rect; for (int32 i = 0; message->FindRect("rect", i, &rect) == B_OK; i++) region.Include(rect); fView->AsyncRedraw(region); break; } default: BApplication::MessageReceived(message); break; } }
// Draw void IconValueView::Draw(BRect updateRect) { BRect r; BRegion originalClippingRegion; GetClippingRegion(&originalClippingRegion); if (fIcon) { BRect b(Bounds()); // layout icon in the center r = fIcon->Bounds(); r.OffsetTo(floorf(b.left + b.Width() / 2.0 - r.Width() / 2.0), floorf(b.top + b.Height() / 2.0 - r.Height() / 2.0)); if (fIcon->ColorSpace() == B_RGBA32 || fIcon->ColorSpace() == B_RGBA32_BIG) { // set up transparent drawing and let // the base class draw the entire background SetHighColor(255, 255, 255, 255); SetDrawingMode(B_OP_ALPHA); SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); } else { // constrain clipping region to exclude bitmap BRegion region = originalClippingRegion; region.Exclude(r); ConstrainClippingRegion(®ion); } } // draw surrouing area (and possibly background for bitmap) PropertyEditorView::Draw(updateRect); ConstrainClippingRegion(&originalClippingRegion); if (fIcon) { DrawBitmap(fIcon, r.LeftTop()); } }
void KouhoView::HighlightPartial( int32 begin, int32 end ) { BRegion region; GetTextRegion( begin, end, ®ion ); highlightRect = region.RectAt( 0 ); Invalidate( highlightRect ); }
void WorkspacesView::_DrawWorkspace(DrawingEngine* drawingEngine, BRegion& redraw, int32 index) { BRect rect = _WorkspaceAt(index); Workspace workspace(*Window()->Desktop(), index); bool active = workspace.IsCurrent(); if (active) { // draw active frame rgb_color black = (rgb_color){ 0, 0, 0, 255 }; drawingEngine->StrokeRect(rect, black); } else if (index == fSelectedWorkspace) { rgb_color gray = (rgb_color){ 80, 80, 80, 255 }; drawingEngine->StrokeRect(rect, gray); } rect.InsetBy(1, 1); rgb_color color = workspace.Color(); if (!active) _DarkenColor(color); // draw windows BRegion backgroundRegion = redraw; // TODO: would be nice to get the real update region here BRect screenFrame = _ScreenFrame(index); BRegion workspaceRegion(rect); backgroundRegion.IntersectWith(&workspaceRegion); drawingEngine->ConstrainClippingRegion(&backgroundRegion); ServerFont font = fDrawState->Font(); font.SetSize(fWindow->ServerWindow()->App()->PlainFont().Size()); float reducedSize = ceilf(max_c(8.0f, min_c(Frame().Height(), Frame().Width()) / 15)); if (font.Size() > reducedSize) font.SetSize(reducedSize); fDrawState->SetFont(font); drawingEngine->SetFont(font); // We draw from top down and cut the window out of the clipping region // which reduces the flickering ::Window* window; BPoint leftTop; while (workspace.GetPreviousWindow(window, leftTop) == B_OK) { _DrawWindow(drawingEngine, rect, screenFrame, window, leftTop, backgroundRegion, active); } // draw background drawingEngine->FillRect(rect, color); drawingEngine->ConstrainClippingRegion(&redraw); }
bool View::RemoveChild(View* view) { if (view == NULL || view->fParent != this) { printf("View::RemoveChild(%p - %s) - View is not child of " "this (%p) view!\n", view, view ? view->Name() : NULL, this); return false; } view->fParent = NULL; if (fLastChild == view) fLastChild = view->fPreviousSibling; // view->fNextSibling would be NULL if (fFirstChild == view ) fFirstChild = view->fNextSibling; // view->fPreviousSibling would be NULL // connect child before and after view if (view->fPreviousSibling) view->fPreviousSibling->fNextSibling = view->fNextSibling; if (view->fNextSibling) view->fNextSibling->fPreviousSibling = view->fPreviousSibling; // view has no siblings anymore view->fPreviousSibling = NULL; view->fNextSibling = NULL; if (view->IsVisible()) { Overlay* overlay = view->_Overlay(); if (overlay != NULL) overlay->Hide(); RebuildClipping(false); } if (fWindow) { view->DetachedFromWindow(); if (fVisible && view->IsVisible()) { // trigger redraw IntRect clippedFrame = view->Frame(); ConvertToVisibleInTopView(&clippedFrame); BRegion* dirty = fWindow->GetRegion(); if (dirty) { dirty->Set((clipping_rect)clippedFrame); fWindow->MarkContentDirtyAsync(*dirty); fWindow->RecycleRegion(dirty); } } } return true; }
void MouseView::MouseDown(BPoint where) { BMessage *mouseMsg = Window()->CurrentMessage(); fButtons = mouseMsg->FindInt32("buttons"); int32 modifiers = mouseMsg->FindInt32("modifiers"); if (modifiers & B_CONTROL_KEY) { if (modifiers & B_COMMAND_KEY) fButtons = B_TERTIARY_MOUSE_BUTTON; else fButtons = B_SECONDARY_MOUSE_BUTTON; } // Get the current clipping region before requesting any updates. // Otherwise those parts would be excluded from the region. BRegion clipping; GetClippingRegion(&clipping); if (fOldButtons != fButtons) { Invalidate(_ButtonsRect()); fOldButtons = fButtons; } const int32* offset = getButtonOffsets(fType); int32 button = -1; for (int32 i = 0; i <= fType; i++) { if (_ButtonRect(offset, i).Contains(where)) { button = i; break; } } if (button < 0) return; // We are setup to receive all mouse events, even if our window // is not active, so make sure that we don't display the menu when // the user clicked inside our view, but another window is on top. if (clipping.Contains(where)) { button = _ConvertFromVisualOrder(button); BPopUpMenu menu("Mouse Map Menu"); BMessage message(kMsgMouseMap); message.AddInt32("button", button); menu.AddItem(new BMenuItem("1", new BMessage(message))); menu.AddItem(new BMenuItem("2", new BMessage(message))); menu.AddItem(new BMenuItem("3", new BMessage(message))); menu.ItemAt(getMappingNumber(fSettings.Mapping(button))) ->SetMarked(true); menu.SetTargetForItems(Window()); ConvertToScreen(&where); menu.Go(where, true); } }
void View::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion) { if (!fVisible || !fWindow) { fScrollingOffset.x += x; fScrollingOffset.y += y; return; } // blitting version, invalidates // old contents // remember old bounds for tracking dirty region IntRect oldBounds(Bounds()); // NOTE: using ConvertToVisibleInTopView() // instead of ConvertToScreen(), this makes // sure we don't try to move or invalidate an // area hidden underneath the parent view ConvertToVisibleInTopView(&oldBounds); // find the area of the view that can be scrolled, // contents are shifted in the opposite direction from scrolling IntRect stillVisibleBounds(oldBounds); stillVisibleBounds.OffsetBy(x, y); stillVisibleBounds = stillVisibleBounds & oldBounds; fScrollingOffset.x += x; fScrollingOffset.y += y; // do the blit, this will make sure // that other more complex dirty regions // are taken care of BRegion* copyRegion = fWindow->GetRegion(); if (!copyRegion) return; copyRegion->Set((clipping_rect)stillVisibleBounds); fWindow->CopyContents(copyRegion, -x, -y); // find the dirty region as far as we are // concerned BRegion* dirty = copyRegion; // reuse copyRegion and call it dirty dirty->Set((clipping_rect)oldBounds); stillVisibleBounds.OffsetBy(-x, -y); dirty->Exclude((clipping_rect)stillVisibleBounds); dirtyRegion->Include(dirty); fWindow->RecycleRegion(dirty); // the screen clipping of this view and it's // childs is no longer valid InvalidateScreenClipping(); RebuildClipping(false); }
virtual void Draw(BRect updateRect) { BRegion region; GetClippingRegion(®ion); BMessage message(MSG_REDRAW); int32 count = region.CountRects(); for (int32 i = 0; i < count; i++) message.AddRect("rect", region.RectAt(i)); be_app->PostMessage(&message); }
static void set_clipping_rects(View* view, const BRect* rects, uint32 numRects) { // TODO: This might be too slow, we should copy the rects // directly to BRegion's internal data BRegion region; for (uint32 c = 0; c < numRects; c++) region.Include(rects[c]); view->SetUserClipping(®ion); view->Window()->ServerWindow()->UpdateCurrentDrawingRegion(); }
void TPanelWindowView::Draw( BRect updateRect ) { BRegion Region; Region.Include(updateRect); ConstrainClippingRegion(&Region); float w, h; w = Bounds().Width(); h = Bounds().Height(); SetHighColor( fColor2 ); FillRect( BRect( 0, 0, h, h ) ); FillRect( BRect( w-h, 0, w, h ) ); FillRect( BRect( h/2, 0, w-(h/2), h/2) ); FillRect( BRect( 0, h/2, w, h ) ); SetHighColor( 196, 196, 176 ); FillRect( BRect( 0, h - 2, w, h ) ); fPanels.Lock(); for ( int i=0; i<fPanels.CountItems(); i++ ) { TInnerPanel *panel = fPanels.ItemAt(i); if ( panel->Frame().Intersects( updateRect ) ) { BRect rect( panel->Frame() ); if ( rect.left < updateRect.left ) rect.left = updateRect.left; if ( rect.right > updateRect.right ) rect.right = updateRect.right; if ( rect.top < updateRect.top ) rect.top = updateRect.top; if ( rect.bottom > updateRect.bottom ) rect.bottom = updateRect.bottom; panel->Draw(rect); } } fPanels.Unlock(); if ( fDrawOuterFrame ) { SetDrawingMode( B_OP_COPY ); SetHighColor( fOuterFrameColor ); BRect bounds = Bounds(); StrokeLine( bounds.LeftTop(), bounds.RightTop() ); StrokeLine( bounds.LeftTop(), bounds.LeftBottom() ); StrokeLine( bounds.RightTop(), bounds.RightBottom() ); } ConstrainClippingRegion(NULL); }
void View::RebuildClipping(bool deep) { // the clipping spans over the bounds area fLocalClipping.Set((clipping_rect)Bounds()); if (View* child = FirstChild()) { // if this view does not draw over children, // exclude all children from the clipping if ((fFlags & B_DRAW_ON_CHILDREN) == 0) { BRegion* childrenRegion = fWindow->GetRegion(); if (!childrenRegion) return; for (; child; child = child->NextSibling()) { if (child->IsVisible()) childrenRegion->Include((clipping_rect)child->Frame()); } fLocalClipping.Exclude(childrenRegion); fWindow->RecycleRegion(childrenRegion); } // if the operation is "deep", make children rebuild their // clipping too if (deep) { for (child = FirstChild(); child; child = child->NextSibling()) child->RebuildClipping(true); } } // add the user clipping in case there is one if (fDrawState->HasClipping()) { // NOTE: in case the user sets a user defined clipping region, // rebuilding the clipping is a bit more expensive because there // is no separate "drawing region"... on the other // hand, views for which this feature is actually used will // probably not have any children, so it is not that expensive // after all if (fUserClipping == NULL) { fUserClipping = new (nothrow) BRegion; if (fUserClipping == NULL) return; } fDrawState->GetCombinedClippingRegion(fUserClipping); } else { delete fUserClipping; fUserClipping = NULL; } delete fScreenAndUserClipping; fScreenAndUserClipping = NULL; fScreenClippingValid = false; }
void DrawState::ReadFromLink(BPrivate::LinkReceiver& link) { ViewSetStateInfo info; link.Read<ViewSetStateInfo>(&info); fPenLocation = info.penLocation; fPenSize = info.penSize; fHighColor = info.highColor; fLowColor = info.lowColor; fPattern = info.pattern; fDrawingMode = info.drawingMode; fOrigin = info.origin; fScale = info.scale; fTransform = info.transform; fLineJoinMode = info.lineJoin; fLineCapMode = info.lineCap; fMiterLimit = info.miterLimit; fFillRule = info.fillRule; fAlphaSrcMode = info.alphaSourceMode; fAlphaFncMode = info.alphaFunctionMode; fFontAliasing = info.fontAntialiasing; if (fPreviousState != NULL) { fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin; fCombinedScale = fPreviousState->fCombinedScale * fScale; fCombinedTransform = fPreviousState->fCombinedTransform * fTransform; } else { fCombinedOrigin = fOrigin; fCombinedScale = fScale; fCombinedTransform = fTransform; } // read clipping // TODO: This could be optimized, but the user clipping regions are rarely // used, so it's low priority... int32 clipRectCount; link.Read<int32>(&clipRectCount); if (clipRectCount >= 0) { BRegion region; BRect rect; for (int32 i = 0; i < clipRectCount; i++) { link.Read<BRect>(&rect); region.Include(rect); } SetClippingRegion(®ion); } else { // No user clipping used SetClippingRegion(NULL); } }
void BPrintJob::_RecurseView(BView* view, BPoint origin, BPicture* picture, BRect rect) { ASSERT(picture != NULL); BRegion region; region.Set(BRect(rect.left, rect.top, rect.right, rect.bottom)); view->fState->print_rect = rect; view->AppendToPicture(picture); view->PushState(); view->SetOrigin(origin); view->ConstrainClippingRegion(®ion); if (view->ViewColor() != B_TRANSPARENT_COLOR) { rgb_color highColor = view->HighColor(); view->SetHighColor(view->ViewColor()); view->FillRect(rect); view->SetHighColor(highColor); } view->fIsPrinting = true; view->Draw(rect); view->fIsPrinting = false; view->PopState(); view->EndPicture(); BView* child = view->ChildAt(0); while (child != NULL) { if ((child->Flags() & B_WILL_DRAW) && !child->IsHidden()) { BPoint leftTop(view->Bounds().LeftTop() + child->Frame().LeftTop()); BRect printRect(rect.OffsetToCopy(rect.LeftTop() - leftTop) & child->Bounds()); if (printRect.IsValid()) _RecurseView(child, origin + leftTop, picture, printRect); } child = child->NextSibling(); } if ((view->Flags() & B_DRAW_ON_CHILDREN) != 0) { view->AppendToPicture(picture); view->PushState(); view->SetOrigin(origin); view->ConstrainClippingRegion(®ion); view->fIsPrinting = true; view->DrawAfterChildren(rect); view->fIsPrinting = false; view->PopState(); view->EndPicture(); } }
void PadView::MouseDown(BPoint where) { BWindow* window = Window(); if (window == NULL) return; BRegion region; GetClippingRegion(®ion); if (!region.Contains(where)) return; bool handle = true; for (int32 i = 0; BView* child = ChildAt(i); i++) { if (child->Frame().Contains(where)) { handle = false; break; } } if (!handle) return; BMessage* message = window->CurrentMessage(); if (message == NULL) return; uint32 buttons; message->FindInt32("buttons", (int32*)&buttons); if (buttons & B_SECONDARY_MOUSE_BUTTON) { BRect r = Bounds(); r.InsetBy(2.0, 2.0); r.top += 6.0; if (r.Contains(where)) { DisplayMenu(where); } else { // sends the window to the back window->Activate(false); } } else { if (system_time() - fClickTime < sActivationDelay) { window->Minimize(true); fClickTime = 0; } else { window->Activate(); fDragOffset = ConvertToScreen(where) - window->Frame().LeftTop(); fDragging = true; SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); fClickTime = system_time(); } } }
static void set_clipping_rects(void* _context, size_t numRects, const BRect rects[]) { DrawingContext* context = reinterpret_cast<DrawingContext *>(_context); // TODO: This might be too slow, we should copy the rects // directly to BRegion's internal data BRegion region; for (uint32 c = 0; c < numRects; c++) region.Include(rects[c]); context->SetUserClipping(®ion); context->UpdateCurrentDrawingRegion(); }