Exemple #1
0
void
ActivityView::_DrawHistory(bool drawBackground)
{
	_UpdateOffscreenBitmap();

	BView* view = this;
	if (fOffscreen != NULL) {
		fOffscreen->Lock();
		view = _OffscreenView();
	}

	BRect frame = _HistoryFrame();
	BRect outerFrame = frame.InsetByCopy(-2, -2);

	// draw the outer frame
	uint32 flags = 0;
	if (!drawBackground)
		flags |= BControlLook::B_BLEND_FRAME;
	be_control_look->DrawTextControlBorder(this, outerFrame,
		outerFrame, fLegendBackgroundColor, flags);

	// convert to offscreen view if necessary
	if (view != this)
		frame.OffsetTo(B_ORIGIN);

	view->SetLowColor(fHistoryBackgroundColor);
	view->FillRect(frame, B_SOLID_LOW);

	uint32 step = 2;
	uint32 resolution = fDrawResolution;
	if (fDrawResolution > 1) {
		step = 1;
		resolution--;
	}

	// We would get a negative number of steps which isn't a good idea.
	if (frame.IntegerWidth() <= 10)
		return;

	uint32 width = frame.IntegerWidth() - 10;
	uint32 steps = width / step;
	bigtime_t timeStep = RefreshInterval() * resolution;
	bigtime_t now = system_time();

	// Draw scale
	// TODO: add second markers?

	view->SetPenSize(1);

	rgb_color scaleColor = view->LowColor();
	uint32 average = (scaleColor.red + scaleColor.green + scaleColor.blue) / 3;
	if (average < 96)
		scaleColor = tint_color(scaleColor, B_LIGHTEN_2_TINT);
	else
		scaleColor = tint_color(scaleColor, B_DARKEN_2_TINT);

	view->SetHighColor(scaleColor);
	view->StrokeLine(BPoint(frame.left, frame.top + frame.Height() / 2),
		BPoint(frame.right, frame.top + frame.Height() / 2));

	// Draw values

	view->SetPenSize(1.5);
	BAutolock _(fSourcesLock);

	for (uint32 i = fSources.CountItems(); i-- > 0;) {
		ViewHistory* viewValues = fViewValues.ItemAt(i);
		DataSource* source = fSources.ItemAt(i);
		DataHistory* values = fValues.ItemAt(i);

		viewValues->Update(values, steps, fDrawResolution, now, timeStep,
			RefreshInterval());

		if (viewValues->Start() >= (int32)steps - 1)
			continue;

		uint32 x = viewValues->Start() * step;

		bool first = true;

		view->SetHighColor(source->Color());
		view->SetLineMode(B_BUTT_CAP, B_ROUND_JOIN);
		view->MovePenTo(B_ORIGIN);

		try {
			view->BeginLineArray(steps - viewValues->Start() - 1);

			BPoint prev;

			for (uint32 j = viewValues->Start(); j < steps; x += step, j++) {
				float y = _PositionForValue(source, values,
					viewValues->ValueAt(j));

				if (first) {
					first = false;
				} else
					view->AddLine(prev, BPoint(x, y), source->Color());

				prev.Set(x, y);
			}

		} catch (std::bad_alloc) {
			// Not enough memory to allocate the line array.
			// TODO we could try to draw using the slower but less memory
			// consuming solution using StrokeLine.
		}

		view->EndLineArray();
	}

	// TODO: add marks when an app started or quit
	view->Sync();
	if (fOffscreen != NULL) {
		fOffscreen->Unlock();
		DrawBitmap(fOffscreen, outerFrame.LeftTop());
	}
}
Exemple #2
0
void MediaJack::_drawInto(
	BView *target,
	BRect targetRect,
	int32 layout)
{
	D_METHOD(("MediaJack::_drawInto()\n"));

	bool selected = isConnecting() || isSelected();
	switch (layout)
	{
		case MediaRoutingView::M_ICON_VIEW:
		{
			if (isInput())
			{
				BRect r;
				BPoint p;

				// fill rect
				r = targetRect;
				target->SetLowColor(M_GRAY_COLOR);
				r.left += 2.0;
				target->FillRect(r, B_SOLID_LOW);

				// draw connection point
				r = targetRect;
				p.Set(0.0, Frame().Height() / 2.0 - 2.0);
				target->BeginLineArray(4);
				{
					target->AddLine(r.LeftTop(),
									p,
									M_DARK_GRAY_COLOR);
					target->AddLine(r.LeftTop() + BPoint(1.0, 0.0),
									p + BPoint(1.0, 0.0),
									M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 5.0),
									r.LeftBottom(),
									M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 5.0),
									r.LeftBottom() + BPoint(1.0, 0.0),
									M_LIGHT_GRAY_COLOR);
				}
				target->EndLineArray();

				if (isConnected() || isConnecting())
				{
					target->BeginLineArray(11);
					{
						target->AddLine(p, p, M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(0.0, 4.0), p + BPoint(0.0, 4.0), M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 0.0), p + BPoint(4.0, 0.0), M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 4.0), p + BPoint(4.0, 4.0), M_LIGHT_GRAY_COLOR);
						target->AddLine(p + BPoint(4.0, 1.0), p + BPoint(4.0, 3.0), M_LIGHT_GRAY_COLOR);
						target->AddLine(p + BPoint(0.0, 1.0), p + BPoint(2.0, 1.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(3.0, 1.0), p + BPoint(3.0, 1.0), M_MED_GRAY_COLOR);
						target->AddLine(p + BPoint(0.0, 2.0), p + BPoint(2.0, 2.0), selected ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR);
						target->AddLine(p + BPoint(3.0, 2.0), p + BPoint(3.0, 2.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(0.0, 3.0), p + BPoint(2.0, 3.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(3.0, 3.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					}
					target->EndLineArray();
				}
				else
				{
					target->BeginLineArray(7);
					{
						target->AddLine(p, p + BPoint(0.0, 4.0), M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 0.0), p + BPoint(4.0, 0.0), M_DARK_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 4.0), p + BPoint(4.0, 4.0), M_LIGHT_GRAY_COLOR);
						target->AddLine(p + BPoint(4.0, 1.0), p + BPoint(4.0, 3.0), M_LIGHT_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(3.0, 1.0), M_MED_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 2.0), p + BPoint(3.0, 2.0), M_MED_GRAY_COLOR);
						target->AddLine(p + BPoint(1.0, 3.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					}
					target->EndLineArray();
				}

				// draw abbreviation string
				BFont font(be_plain_font);
				font_height fh;
				font.SetSize(font.Size() - 2.0);
				font.GetHeight(&fh);
				p.x += 7.0;
				p.y = (Frame().Height() / 2.0) + (fh.ascent / 2.0);
				target->SetFont(&font);
				target->SetDrawingMode(B_OP_OVER);
				target->SetHighColor((isConnected() || isConnecting()) ?
									  M_MED_GRAY_COLOR :
									  M_DARK_GRAY_COLOR);
				target->DrawString(m_abbreviation.String(), p);
			}
			else if (isOutput())
			{
				BRect r;
				BPoint p;

				// fill rect
				r = targetRect;
				target->SetLowColor(M_GRAY_COLOR);
				r.right -= 2.0;
				target->FillRect(r, B_SOLID_LOW);

				// draw connection point
				r = targetRect;
				p.Set(targetRect.right - 4.0, Frame().Height() / 2.0 - 2.0);
				target->BeginLineArray(4);
				{
					target->AddLine(r.RightTop(),
									p + BPoint(4.0, 0.0),
									M_DARK_GRAY_COLOR);
					target->AddLine(r.RightTop() + BPoint(-1.0, 0.0),
									p + BPoint(3.0, 0.0),
									M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 5.0),
									r.RightBottom(),
									M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 5.0),
									r.RightBottom() + BPoint(-1.0, 0.0),
									M_MED_GRAY_COLOR);
				}
				target->EndLineArray();

				if (isConnected() || isConnecting())
				{
					target->BeginLineArray(11);
					target->AddLine(p + BPoint(4.0, 0.0), p + BPoint(4.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 4.0), p + BPoint(4.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p, p + BPoint(3.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 1.0), p + BPoint(0.0, 3.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 4.0), p + BPoint(3.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(1.0, 1.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 1.0), p + BPoint(4.0, 1.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 2.0), p + BPoint(1.0, 2.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 2.0), p + BPoint(4.0, 2.0), selected ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 3.0), p + BPoint(1.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 3.0), p + BPoint(4.0, 3.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->EndLineArray();
				}
				else
				{
					target->BeginLineArray(7);
					target->AddLine(p + BPoint(4.0, 0.0), p + BPoint(4.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p, p + BPoint(3.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 1.0), p + BPoint(0.0, 3.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 4.0), p + BPoint(3.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(3.0, 1.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 2.0), p + BPoint(3.0, 2.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 3.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					target->EndLineArray();
				}

				// draw abbreviation string
				BFont font(be_plain_font);
				font_height fh;
				font.SetSize(font.Size() - 2.0);
				font.GetHeight(&fh);
				p.x -= font.StringWidth(m_abbreviation.String()) + 2.0;
				p.y = (Frame().Height() / 2.0) + (fh.ascent / 2.0);
				target->SetFont(&font);
				target->SetDrawingMode(B_OP_OVER);
				target->SetHighColor((isConnected() || isConnecting()) ?
									  M_MED_GRAY_COLOR :
									  M_DARK_GRAY_COLOR);
				target->DrawString(m_abbreviation.String(), p);
			}
			break;
		}
		case MediaRoutingView::M_MINI_ICON_VIEW:
		{
			if (isInput())
			{
				BRect r;
				BPoint p;

				// fill rect
				r = targetRect;
				target->SetLowColor(M_GRAY_COLOR);
				r.top += 2.0;
				target->FillRect(r, B_SOLID_LOW);

				// draw connection point
				r = targetRect;
				p.Set(Frame().Width() / 2.0 - 2.0, 0.0);
				target->BeginLineArray(4);
				{
					target->AddLine(r.LeftTop(),
									p,
									M_DARK_GRAY_COLOR);
					target->AddLine(r.LeftTop() + BPoint(0.0, 1.0),
									p + BPoint(0.0, 1.0),
									M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(5.0, 0.0),
									r.RightTop(),
									M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(5.0, 1.0),
									r.RightTop() + BPoint(0.0, 1.0),
									M_LIGHT_GRAY_COLOR);
				}
				target->EndLineArray();
				if (isConnected() || isConnecting())
				{
					target->BeginLineArray(11);
					target->AddLine(p, p, M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 0.0), p + BPoint(4.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 1.0), p + BPoint(0.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 1.0), p + BPoint(4.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 4.0), p + BPoint(3.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 0.0), p + BPoint(1.0, 2.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 3.0), p + BPoint(1.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 0.0), p + BPoint(2.0, 2.0), selected ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 3.0), p + BPoint(2.0, 3.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 0.0), p + BPoint(3.0, 2.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 3.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					target->EndLineArray();
				}
				else
				{
					target->BeginLineArray(7);
					target->AddLine(p, p + BPoint(4.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(0.0, 1.0), p + BPoint(0.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 1.0), p + BPoint(4.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 4.0), p + BPoint(3.0, 4.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(1.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 1.0), p + BPoint(2.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 1.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					target->EndLineArray();
				}
			}
			else if (isOutput())
			{
				BRect r = targetRect;
				BPoint p;

				// fill rect
				r = targetRect;
				target->SetLowColor(M_GRAY_COLOR);
				r.bottom -= 2.0;
				target->FillRect(r, B_SOLID_LOW);

				// draw connection point
				r = targetRect;
				p.Set(Frame().Width() / 2.0 - 2.0, targetRect.bottom - 4.0);
				target->BeginLineArray(4);
				{
					target->AddLine(r.LeftBottom(),
									p + BPoint(0.0, 4.0),
									M_DARK_GRAY_COLOR);
					target->AddLine(r.LeftBottom() + BPoint(0.0, -1.0),
									p + BPoint(0.0, 3.0),
									M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(5.0, 4.0),
									r.RightBottom(),
									M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(5.0, 3.0),
									r.RightBottom() + BPoint(0.0, -1.0),
									M_MED_GRAY_COLOR);
				}
				target->EndLineArray();
				if (isConnected() || isConnecting())
				{
					target->BeginLineArray(11);
					target->AddLine(p + BPoint(0.0, 4.0), p + BPoint(0.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 4.0), p + BPoint(4.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p, p + BPoint(0.0, 3.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 0.0), p + BPoint(3.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 0.0), p + BPoint(4.0, 3.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(1.0, 1.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 2.0), p + BPoint(1.0, 4.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 1.0), p + BPoint(2.0, 1.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 2.0), p + BPoint(2.0, 4.0), selected ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 1.0), p + BPoint(3.0, 1.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 2.0), p + BPoint(3.0, 4.0), selected ? M_BLUE_COLOR : M_DARK_GRAY_COLOR);
					target->EndLineArray();
				}
				else
				{
					target->BeginLineArray(7);
					target->AddLine(p + BPoint(0.0, 4.0), p + BPoint(4.0, 4.0), M_DARK_GRAY_COLOR);
					target->AddLine(p, p + BPoint(0.0, 3.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 0.0), p + BPoint(3.0, 0.0), M_DARK_GRAY_COLOR);
					target->AddLine(p + BPoint(4.0, 0.0), p + BPoint(4.0, 3.0), M_LIGHT_GRAY_COLOR);
					target->AddLine(p + BPoint(1.0, 1.0), p + BPoint(1.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(2.0, 1.0), p + BPoint(2.0, 3.0), M_MED_GRAY_COLOR);
					target->AddLine(p + BPoint(3.0, 1.0), p + BPoint(3.0, 3.0), M_MED_GRAY_COLOR);
					target->EndLineArray();
				}
			}
			break;
		}
	}
}
Exemple #3
0
void
ShortcutsSpec::DrawItemColumn(BView* owner, BRect item_column_rect, 
	int32 column_index, bool columnSelected, bool complete)
{
	const float STRING_COLUMN_LEFT_MARGIN = 25.0f; // 16 for the icon,+9 empty

	rgb_color color;
	bool selected = IsSelected();
	if (selected)
		color = columnSelected ? BeBackgroundGrey : BeListSelectGrey;
	else
		color = BeInactiveControlGrey;
	owner->SetLowColor(color);
	owner->SetDrawingMode(B_OP_COPY);
	owner->SetHighColor(color);
	owner->FillRect(item_column_rect);

	const char* text = GetCellText(column_index);

	if (text == NULL)
		return;
	
	float textWidth = _viewFont.StringWidth(text);
	BPoint point;
	rgb_color lowColor = color;

	if (column_index == STRING_COLUMN_INDEX) {
		// left justified
		point.Set(item_column_rect.left + STRING_COLUMN_LEFT_MARGIN, 
			item_column_rect.top + fTextOffset);
		
		item_column_rect.left = point.x;
			// keep text from drawing into icon area

		// scroll if too wide
		float rectWidth = item_column_rect.Width() - STRING_COLUMN_LEFT_MARGIN;
		float extra = textWidth - rectWidth;
		if (extra > 0.0f)
			point.x -= extra;
	} else {
		if ((column_index < NUM_META_COLUMNS) && (text[0] == '('))
			return; // don't draw for this ...
		
		if ((column_index <= NUM_META_COLUMNS) && (text[0] == '\0'))
			return; // don't draw for this ...

		// centered
		point.Set((item_column_rect.left + item_column_rect.right) / 2.0, 
			item_column_rect.top + fTextOffset);
		_CacheViewFont(owner);
		point.x -= textWidth / 2.0f;
	}

	BRegion Region;
	Region.Include(item_column_rect);
	owner->ConstrainClippingRegion(&Region);
	if (column_index != STRING_COLUMN_INDEX) {
		const float KEY_MARGIN = 3.0f;
		const float CORNER_RADIUS = 3.0f;
		_CacheViewFont(owner);

		// How about I draw a nice "key" background for this one?
		BRect textRect(point.x - KEY_MARGIN, (point.y-_fontHeight) - KEY_MARGIN
			, point.x + textWidth + KEY_MARGIN - 2.0f, point.y + KEY_MARGIN);
		
		if (column_index == KEY_COLUMN_INDEX)
			lowColor = ReallyLightPurple;
		else
			lowColor = LightYellow;
		
		owner->SetHighColor(lowColor);
		owner->FillRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS);
		owner->SetHighColor(Black);
		owner->StrokeRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS);
	}

	owner->SetHighColor(Black);
	owner->SetLowColor(lowColor);
	owner->DrawString(text, point);
	// with a cursor at the end if highlighted
	if (column_index == STRING_COLUMN_INDEX) {
		// Draw cursor
		if ((columnSelected) && (selected)) {
			point.x += textWidth;
			point.y += (fTextOffset / 4.0f);

			BPoint pt2 = point;
			pt2.y -= fTextOffset;
			owner->StrokeLine(point, pt2);

			fCursorPt1 = point;
			fCursorPt2 = pt2;
			fCursorPtsValid = true;
		}

		BRegion bitmapRegion;
		item_column_rect.left	-= (STRING_COLUMN_LEFT_MARGIN - 4.0f);
		item_column_rect.right	= item_column_rect.left + 16.0f;
		item_column_rect.top	+= 3.0f;
		item_column_rect.bottom	= item_column_rect.top + 16.0f;

		bitmapRegion.Include(item_column_rect);
		owner->ConstrainClippingRegion(&bitmapRegion);
		owner->SetDrawingMode(B_OP_OVER);

		if ((fCommand != NULL) && (fCommand[0] == '*'))
			owner->DrawBitmap(_actuatorBitmaps[fBitmapValid ? 1 : 0], 
				ICON_BITMAP_RECT, item_column_rect);
		else
			// Draw icon, if any
			if (fBitmapValid) 
				owner->DrawBitmap(&fBitmap, ICON_BITMAP_RECT, 
					item_column_rect);
	}

	owner->SetDrawingMode(B_OP_COPY);
	owner->ConstrainClippingRegion(NULL);
}
Exemple #4
0
void
BRadioButton::Draw(BRect updateRect)
{
	if (Window() == NULL) return;

	BFont font;
	GetFont(&font);
	font_height fontHeight;
	font.GetHeight(&fontHeight);
	float sHeight = fontHeight.ascent + fontHeight.descent;

	BRect rect = Frame().OffsetToSelf(B_ORIGIN);
	rect.InsetBy(5, (rect.Height() - sHeight) / 2);
	if (rect.IsValid() == false) return;

	if ((IsFocus() || IsFocusChanging()) && IsEnabled() && Label() != NULL) {
		BPoint penLocation;
		penLocation.Set(rect.left + rect.Height() + 5, rect.Center().y + sHeight / 2 + 1);

		SetHighColor((IsFocus() && Window()->IsActivate()) ? ui_color(B_NAVIGATION_BASE_COLOR) : ViewColor());
		StrokeLine(penLocation, penLocation + BPoint(font.StringWidth(Label()), 0));
	}

	if (IsFocusChanging()) return;

	rgb_color shineColor = ui_color(B_SHINE_COLOR);
	rgb_color shadowColor = ui_color(B_SHADOW_COLOR);

	if (!IsEnabled()) {
		shineColor.disable(ViewColor());
		shadowColor.disable(ViewColor());
	}

	rect.right = rect.left + rect.Height();
	SetHighColor(shineColor.mix_copy(0, 0, 0, 5));
	FillEllipse(rect);
	SetHighColor(shineColor);
	StrokeArc(rect, 225, 180);
	SetHighColor(shadowColor);
	StrokeArc(rect, 45, 180);

	if (Value() == B_CONTROL_ON) {
		SetHighColor(shadowColor.mix_copy(255, 255, 255, 50));
		BRect r = rect.InsetByCopy(3, 3);
		FillEllipse(r);
	}

	if (Label() != NULL) {
		BPoint penLocation;
		penLocation.x = rect.right + 5;
		penLocation.y = rect.Center().y - sHeight / 2.f;
		penLocation.y += fontHeight.ascent + 1;

		SetHighColor(IsEnabled() ? ui_color(B_PANEL_TEXT_COLOR) : ui_color(B_SHINE_COLOR).disable(ViewColor()));
		SetLowColor(ViewColor());

		DrawString(Label(), penLocation);
		if (!IsEnabled()) {
			SetHighColor(ui_color(B_SHADOW_COLOR).disable(ViewColor()));
			DrawString(Label(), penLocation - BPoint(1, 1));
		}
	}
}