// 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 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 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 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); }
void SimpleTransformTest::TransformRegionArray() { BRegion regions[2]; regions[0].Include(BRect( 5.0, 5.0, 20.0, 20.0)); regions[0].Include(BRect(10.0, 10.0, 30.0, 30.0)); regions[0].Exclude(BRect(10.0, 20.0, 20.0, 25.0)); regions[1].Include(BRect( 5.0, 5.0, 20.0, 20.0)); regions[1].Include(BRect(10.0, 10.0, 30.0, 30.0)); regions[1].Exclude(BRect(10.0, 20.0, 20.0, 25.0)); BRegion transformedRegions[3]; SimpleTransform specimen; specimen.AddOffset(10.0, 20.0); specimen.SetScale(2.5); specimen.Apply(&transformedRegions[0], ®ions[0], 2); BRegion reference; reference.Include(BRect(22.0, 32.0, 62.0, 72.0)); reference.Include(BRect(35.0, 45.0, 87.0, 97.0)); reference.Exclude(BRect(35.0, 70.0, 61.0, 84.0)); CPPUNIT_ASSERT(transformedRegions[0] == reference); CPPUNIT_ASSERT(transformedRegions[1] == reference); }
void Graphics::setClip( int xClip, int yClip, int wClip, int hClip ) { // TODO SGY see how BeOS manages references here #ifdef DEBUG // for debugging purpouses "scroll lock" disables clipping // if (modifiers() & B_SCROLL_LOCK) return; #endif BRect *rect = new BRect(); xClip += x0 ; yClip += y0 ; rect->left = xClip ; rect->top = yClip ; rect->right = rect->left + wClip - 1 ; rect->bottom = rect->top + hClip - 1 ; newreg.Set( *rect ); BRegion *region = new BRegion(); if( lock() ) { view->GetClippingRegion( region ); region->Exclude( &oldreg ); region->Include( &newreg ); view->ConstrainClippingRegion( region ); unlock(); } oldreg = newreg; delete region ; delete rect ; }
void InsertionIntoEmptyArea::MaximizeEmptyArea(area_ref& ref, BRect target, BRect ignore) { BALMLayout* layout = fView->Layout(); BRegion takenSpace = fView->fTakenSpace; takenSpace.Exclude(ignore); area_info areaInfo(ref, layout); // try to match the target XTab* left = ref.left; while (left->Value() > target.left) { left = layout->XTabAt(areaInfo.left - 1, true); if (left == NULL) break; area_ref newRef = ref; newRef.left = left; BRect frame = newRef.Frame(); frame.InsetBy(1, 1); if (takenSpace.Intersects(frame)) break; areaInfo.left -= 1; ref.left = left; } XTab* right = ref.right; while (right->Value() < target.right) { right = layout->XTabAt(areaInfo.right + 1, true); if (right == NULL) break; area_ref newRef = ref; newRef.right = right; BRect frame = newRef.Frame(); frame.InsetBy(1, 1); if (takenSpace.Intersects(frame)) break; areaInfo.right += 1; ref.right = right; } YTab* top = ref.top; while (top->Value() > target.top) { top = layout->YTabAt(areaInfo.top - 1, true); if (top == NULL) break; area_ref newRef = ref; newRef.top = top; BRect frame = newRef.Frame(); frame.InsetBy(1, 1); if (takenSpace.Intersects(frame)) break; areaInfo.top -= 1; ref.top = top; } YTab* bottom = ref.bottom; while (bottom->Value() < target.bottom) { bottom = layout->YTabAt(areaInfo.bottom + 1, true); if (bottom == NULL) break; area_ref newRef = ref; newRef.bottom = bottom; BRect frame = newRef.Frame(); frame.InsetBy(1, 1); if (takenSpace.Intersects(frame)) break; areaInfo.bottom += 1; ref.bottom = bottom; } // maximize further while (true) { BRect previousFrame = ref.Frame(); left = layout->XTabAt(areaInfo.left - 1, true); right = layout->XTabAt(areaInfo.right + 1, true); top = layout->YTabAt(areaInfo.top - 1, true); bottom = layout->YTabAt(areaInfo.bottom + 1, true); float leftDelta = -1; if (left != NULL) { BRect newFrame(previousFrame); newFrame.left = left->Value(); newFrame.InsetBy(1, 1); if (!takenSpace.Intersects(newFrame)) { leftDelta = previousFrame.Height() * (previousFrame.left - left->Value()); } } float rightDelta = -1; if (right != NULL) { BRect newFrame(previousFrame); newFrame.right = right->Value(); newFrame.InsetBy(1, 1); if (!takenSpace.Intersects(newFrame)) { rightDelta = previousFrame.Height() * (right->Value() - previousFrame.right); } } float topDelta = -1; if (top != NULL) { BRect newFrame(previousFrame); newFrame.top = top->Value(); newFrame.InsetBy(1, 1); if (!takenSpace.Intersects(newFrame)) { topDelta = previousFrame.Width() * (previousFrame.top - top->Value()); } } float bottomDelta = -1; if (bottom != NULL) { BRect newFrame(previousFrame); newFrame.bottom = bottom->Value(); newFrame.InsetBy(1, 1); if (!takenSpace.Intersects(newFrame)) { bottomDelta = previousFrame.Width() * (bottom->Value() - previousFrame.bottom); } } if (leftDelta > 0 && leftDelta > rightDelta && leftDelta > topDelta && leftDelta > bottomDelta) { ref.left = left; areaInfo.left = layout->IndexOf(left, true); } else if (rightDelta > 0 && rightDelta > topDelta && rightDelta > bottomDelta) { ref.right = right; areaInfo.right = layout->IndexOf(right, true); } else if (topDelta > 0 && topDelta > bottomDelta) { ref.top = top; areaInfo.top = layout->IndexOf(top, true); } else if (bottomDelta > 0) { ref.bottom = bottom; areaInfo.bottom = layout->IndexOf(bottom, true); } BRect newFrame = ref.Frame(); if (fuzzy_equal(previousFrame.Width(), newFrame.Width()) && fuzzy_equal(previousFrame.Height(), newFrame.Height())) break; } }
void View::MoveBy(int32 x, int32 y, BRegion* dirtyRegion) { if (x == 0 && y == 0) return; fFrame.OffsetBy(x, y); // to move on screen, we must not be hidden and we must have a parent if (fVisible && fParent && dirtyRegion) { #if 1 // based on redraw on new location // the place were we are now visible IntRect newVisibleBounds(Bounds()); // we can use the frame of the old // local clipping to see which parts need invalidation IntRect oldVisibleBounds(newVisibleBounds); oldVisibleBounds.OffsetBy(-x, -y); ConvertToScreen(&oldVisibleBounds); ConvertToVisibleInTopView(&newVisibleBounds); dirtyRegion->Include((clipping_rect)oldVisibleBounds); // newVisibleBounds already is in screen coords dirtyRegion->Include((clipping_rect)newVisibleBounds); #else // blitting version, invalidates // old contents IntRect oldVisibleBounds(Bounds()); IntRect newVisibleBounds(oldVisibleBounds); oldVisibleBounds.OffsetBy(-x, -y); ConvertToScreen(&oldVisibleBounds); // NOTE: using ConvertToVisibleInTopView() // instead of ConvertToScreen()! see below ConvertToVisibleInTopView(&newVisibleBounds); newVisibleBounds.OffsetBy(-x, -y); // clipping oldVisibleBounds to newVisibleBounds // makes sure we don't copy parts hidden under // parent views BRegion* region = fWindow->GetRegion(); if (region) { region->Set(oldVisibleBounds & newVisibleBounds); fWindow->CopyContents(region, x, y); region->Set(oldVisibleBounds); newVisibleBounds.OffsetBy(x, y); region->Exclude((clipping_rect)newVisibleBounds); dirtyRegion->Include(dirty); fWindow->RecycleRegion(region); } #endif } if (!fParent) { // the top view's screen clipping does not change, // because no parts are clipped away from parent // views _MoveScreenClipping(x, y, true); } else { // parts might have been revealed from underneath // the parent, or might now be hidden underneath // the parent, this is taken care of when building // the screen clipping InvalidateScreenClipping(); } }
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::CopyBits(IntRect src, IntRect dst, BRegion& windowContentClipping) { if (!fVisible || !fWindow) return; // TODO: confirm that in R5 this call is affected by origin and scale // blitting version int32 xOffset = dst.left - src.left; int32 yOffset = dst.top - src.top; // figure out which part can be blittet IntRect visibleSrc(src); ConvertToVisibleInTopView(&visibleSrc); IntRect visibleSrcAtDest(src); visibleSrcAtDest.OffsetBy(xOffset, yOffset); ConvertToVisibleInTopView(&visibleSrcAtDest); // clip src to visible at dest visibleSrcAtDest.OffsetBy(-xOffset, -yOffset); visibleSrc = visibleSrc & visibleSrcAtDest; // do the blit, this will make sure // that other more complex dirty regions // are taken care of BRegion* copyRegion = fWindow->GetRegion(); if (!copyRegion) return; // move src rect to destination here for efficiency reasons visibleSrc.OffsetBy(xOffset, yOffset); // we need to interstect the copyRegion two times, onces // at the source and once at the destination (here done // the other way arround but it doesn't matter) // the reason for this is that we are not supposed to visually // copy children in the source rect and neither to copy onto // children in the destination rect... copyRegion->Set((clipping_rect)visibleSrc); BRegion *screenAndUserClipping = &ScreenAndUserClipping(&windowContentClipping); copyRegion->IntersectWith(screenAndUserClipping); copyRegion->OffsetBy(-xOffset, -yOffset); copyRegion->IntersectWith(screenAndUserClipping); // do the actual blit fWindow->CopyContents(copyRegion, xOffset, yOffset); // find the dirty region as far as we are concerned IntRect dirtyDst(dst); ConvertToVisibleInTopView(&dirtyDst); BRegion* dirty = fWindow->GetRegion(); if (!dirty) { fWindow->RecycleRegion(copyRegion); return; } // offset copyRegion to destination again copyRegion->OffsetBy(xOffset, yOffset); // start with destination given by user dirty->Set((clipping_rect)dirtyDst); // exclude the part that we could copy dirty->Exclude(copyRegion); dirty->IntersectWith(screenAndUserClipping); fWindow->MarkContentDirty(*dirty); fWindow->RecycleRegion(dirty); fWindow->RecycleRegion(copyRegion); }
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); }
void BSlider::DrawBar() { BRect frame = BarFrame(); BView *view = OffscreenView(); if (be_control_look != NULL) { uint32 flags = be_control_look->Flags(this); rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color rightFillColor = fBarColor; rgb_color leftFillColor = fUseFillColor ? fFillColor : fBarColor; be_control_look->DrawSliderBar(view, frame, frame, base, leftFillColor, rightFillColor, Position(), flags, fOrientation); return; } rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lightenmax; rgb_color darken1; rgb_color darken2; rgb_color darkenmax; rgb_color barColor; rgb_color fillColor; if (IsEnabled()) { lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT); darken1 = tint_color(no_tint, B_DARKEN_1_TINT); darken2 = tint_color(no_tint, B_DARKEN_2_TINT); darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); barColor = fBarColor; fillColor = fFillColor; } else { lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT); darken1 = no_tint; darken2 = tint_color(no_tint, B_DARKEN_1_TINT); darkenmax = tint_color(no_tint, B_DARKEN_3_TINT); barColor.red = (fBarColor.red + no_tint.red) / 2; barColor.green = (fBarColor.green + no_tint.green) / 2; barColor.blue = (fBarColor.blue + no_tint.blue) / 2; barColor.alpha = 255; fillColor.red = (fFillColor.red + no_tint.red) / 2; fillColor.green = (fFillColor.green + no_tint.green) / 2; fillColor.blue = (fFillColor.blue + no_tint.blue) / 2; fillColor.alpha = 255; } // exclude the block thumb from the bar filling BRect lowerFrame = frame.InsetByCopy(1, 1); lowerFrame.top++; lowerFrame.left++; BRect upperFrame = lowerFrame; BRect thumbFrame; if (Style() == B_BLOCK_THUMB) { thumbFrame = ThumbFrame(); if (fOrientation == B_HORIZONTAL) { lowerFrame.right = thumbFrame.left; upperFrame.left = thumbFrame.right; } else { lowerFrame.top = thumbFrame.bottom; upperFrame.bottom = thumbFrame.top; } } else if (fUseFillColor) { if (fOrientation == B_HORIZONTAL) { lowerFrame.right = floor(lowerFrame.left - 1 + Position() * (lowerFrame.Width() + 1)); upperFrame.left = lowerFrame.right; } else { lowerFrame.top = floor(lowerFrame.bottom + 1 - Position() * (lowerFrame.Height() + 1)); upperFrame.bottom = lowerFrame.top; } } view->SetHighColor(barColor); view->FillRect(upperFrame); if (Style() == B_BLOCK_THUMB || fUseFillColor) { if (fUseFillColor) view->SetHighColor(fillColor); view->FillRect(lowerFrame); } if (Style() == B_BLOCK_THUMB) { // We don't want to stroke the lines over the thumb PushState(); BRegion region; GetClippingRegion(®ion); region.Exclude(thumbFrame); ConstrainClippingRegion(®ion); } view->SetHighColor(darken1); view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.left + 1.0f, frame.top)); view->StrokeLine(BPoint(frame.left, frame.bottom), BPoint(frame.left + 1.0f, frame.bottom)); view->StrokeLine(BPoint(frame.right - 1.0f, frame.top), BPoint(frame.right, frame.top)); view->SetHighColor(darken2); view->StrokeLine(BPoint(frame.left + 1.0f, frame.top), BPoint(frame.right - 1.0f, frame.top)); view->StrokeLine(BPoint(frame.left, frame.bottom - 1.0f), BPoint(frame.left, frame.top + 1.0f)); view->SetHighColor(lightenmax); view->StrokeLine(BPoint(frame.left + 1.0f, frame.bottom), BPoint(frame.right, frame.bottom)); view->StrokeLine(BPoint(frame.right, frame.bottom - 1.0f), BPoint(frame.right, frame.top + 1.0f)); frame.InsetBy(1.0f, 1.0f); view->SetHighColor(darkenmax); view->StrokeLine(BPoint(frame.left, frame.bottom), BPoint(frame.left, frame.top)); view->StrokeLine(BPoint(frame.left + 1.0f, frame.top), BPoint(frame.right, frame.top)); if (Style() == B_BLOCK_THUMB) PopState(); }
void WorkspacesView::_DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame, const BRect& screenFrame, ::Window* window, BPoint windowPosition, BRegion& backgroundRegion, bool active) { if (window->Feel() == kDesktopWindowFeel || window->IsHidden()) return; BPoint offset = window->Frame().LeftTop() - windowPosition; BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame(), windowPosition); Decorator *decorator = window->Decorator(); BRect tabFrame(0, 0, 0, 0); if (decorator != NULL) tabFrame = decorator->TabRect(); tabFrame = _WindowFrame(workspaceFrame, screenFrame, tabFrame, tabFrame.LeftTop() - offset); if (!workspaceFrame.Intersects(frame) && !workspaceFrame.Intersects(tabFrame)) return; rgb_color activeTabColor = (rgb_color){ 255, 203, 0, 255 }; rgb_color inactiveTabColor = (rgb_color){ 232, 232, 232, 255 }; rgb_color navColor = (rgb_color){ 0, 0, 229, 255 }; if (decorator != NULL) { activeTabColor = decorator->UIColor(B_WINDOW_TAB_COLOR); inactiveTabColor = decorator->UIColor(B_WINDOW_INACTIVE_TAB_COLOR); navColor = decorator->UIColor(B_NAVIGATION_BASE_COLOR); } // TODO: let decorator do this! rgb_color frameColor = (rgb_color){ 180, 180, 180, 255 }; rgb_color white = (rgb_color){ 255, 255, 255, 255 }; rgb_color tabColor = inactiveTabColor; if (window->IsFocus()) tabColor = activeTabColor; if (!active) { _DarkenColor(tabColor); _DarkenColor(frameColor); _DarkenColor(white); } if (window == fSelectedWindow) { frameColor = navColor; } if (tabFrame.left < frame.left) tabFrame.left = frame.left; if (tabFrame.right >= frame.right) tabFrame.right = frame.right - 1; tabFrame.bottom = frame.top - 1; tabFrame.top = min_c(tabFrame.top, tabFrame.bottom); tabFrame = tabFrame & workspaceFrame; if (decorator != NULL && tabFrame.IsValid()) { drawingEngine->FillRect(tabFrame, tabColor); backgroundRegion.Exclude(tabFrame); } drawingEngine->StrokeRect(frame, frameColor); BRect fillFrame = frame.InsetByCopy(1, 1) & workspaceFrame; frame = frame & workspaceFrame; if (!frame.IsValid()) return; // fill the window itself drawingEngine->FillRect(fillFrame, white); // draw title // TODO: the mini-window functionality should probably be moved into the // Window class, so that it has only to be recalculated on demand. With // double buffered windows, this would also open up the door to have a // more detailed preview. BString title(window->Title()); const ServerFont& font = fDrawState->Font(); font.TruncateString(&title, B_TRUNCATE_END, fillFrame.Width() - 4); font_height fontHeight; font.GetHeight(fontHeight); float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); if (title.Length() > 0 && height < frame.Height() - 2) { rgb_color textColor = tint_color(white, B_DARKEN_4_TINT); drawingEngine->SetHighColor(textColor); drawingEngine->SetLowColor(white); float width = font.StringWidth(title.String(), title.Length()); BPoint textOffset; textOffset.x = rintf(frame.left + (frame.Width() - width) / 2); textOffset.y = rintf(frame.top + (frame.Height() - height) / 2 + fontHeight.ascent); drawingEngine->DrawString(title.String(), title.Length(), textOffset); } // prevent the next window down from drawing over this window backgroundRegion.Exclude(frame); }