Пример #1
0
// 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(&region);
		}
	}
	// 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(&region);
	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(&region);
	CPPUNIT_ASSERT(region == reference2);
}
Пример #3
0
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);				
	}	
}
Пример #4
0
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], &regions[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);
}
Пример #6
0
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 ;
}
Пример #7
0
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;
	}
}
Пример #8
0
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();
    }
}
Пример #9
0
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);
        }
    }
}
Пример #10
0
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);
}
Пример #11
0
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);
}
Пример #12
0
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(&region);
		region.Exclude(thumbFrame);
		ConstrainClippingRegion(&region);
	}

	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();
}
Пример #13
0
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);
}