void
GMFilterNameTable::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	JXEditTable::Draw(p, rect);
	if (itsDNDIsValid)
		{
		p.ResetClipRect();
		p.SetLineWidth(kDragLineWidth);
		if (itsCurrentDNDIndex == 0)
			{
			JRect crect =
				GetCellRect(JPoint(1, GetRowCount()));
			p.Line(0, crect.bottom, GetBoundsWidth(), crect.bottom);
			}
		else
			{
			JRect crect =
				GetCellRect(JPoint(1, itsCurrentDNDIndex));
			p.Line(0, crect.top, GetBoundsWidth(), crect.top);
			}
		}
}
Example #2
0
void
JXButton::DrawBorder
	(
	JXWindowPainter&	p,
	const JRect&		origFrame
	)
{
	JSize borderWidth = GetBorderWidth();
	if (borderWidth > 0 && IsActive())
		{
		JRect frame = origFrame;
		if (itsIsReturnButtonFlag)
			{
			p.JPainter::Rect(frame);
			frame.Shrink(1,1);
			borderWidth--;
			}

		if (itsIsPushedFlag)
			{
			JXDrawDownFrame(p, frame, borderWidth);
			}
		else
			{
			JXDrawUpFrame(p, frame, borderWidth);
			}
		}
	else if (borderWidth > 0)
		{
		p.SetLineWidth(borderWidth);
		p.SetPenColor((GetColormap())->GetInactiveLabelColor());
		p.RectInside(origFrame);
		}
}
void
JXImageCheckbox::DrawBorder
	(
	JXWindowPainter&	p,
	const JRect&		frame
	)
{
	const JBoolean drawChecked = DrawChecked();
	const JBoolean isActive    = IsActive();
	const JSize borderWidth    = GetBorderWidth();

	if (drawChecked && isActive)
		{
		JXDrawDownFrame(p, frame, borderWidth);
		}
	else if (isActive)
		{
		JXDrawUpFrame(p, frame, borderWidth);
		}
	else if (borderWidth > 0)
		{
		p.SetLineWidth(borderWidth);
		if (drawChecked)
			{
			p.SetPenColor((GetColormap())->GetWhiteColor());
			}
		else
			{
			p.SetPenColor((GetColormap())->GetInactiveLabelColor());
			}
		p.RectInside(frame);
		}
}
void
JXSearchTextButton::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	const JRect bounds = GetBounds();

	JRect r;
	r.top    = bounds.ycenter() - kArrowHalfHeight;
	r.bottom = r.top + 2*kArrowHalfHeight + 1;
	r.left   = bounds.xcenter() - kArrowHalfWidth;
	r.right  = r.left + 2*kArrowHalfWidth;

	const JColorIndex colorIndex =
		IsActive() ? (p.GetColormap())->GetGrayColor(40) :
					 (p.GetColormap())->GetInactiveLabelColor();
	if (itsFwdFlag)
		{
		r.right++;
		JXFillArrowRight(p, r, colorIndex);
		}
	else
		{
		r.left--;
		JXFillArrowLeft(p, r, colorIndex);
		}
}
Example #5
0
void
JXWidget::DrawBackground
	(
	JXWindowPainter&	p,
	const JRect&		frame
	)
{
	p.SetPenColor(GetCurrBackColor());
	p.SetFilling(kJTrue);
	p.JPainter::Rect(frame);
}
void
JXTabGroup::DrawCloseButton
	(
	const JIndex		index,
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	if (index != itsMouseIndex)
		{
		return;
		}
	else if (!TabCanClose(index))
		{
		itsCloseRect.Set(0,0,0,0);
		return;
		}

	if (itsEdge == kTop || itsEdge == kBottom)
		{
		itsCloseRect.top    = rect.ycenter() - itsCloseImage->GetHeight()/2;
		itsCloseRect.bottom = itsCloseRect.top + itsCloseImage->GetHeight();
		itsCloseRect.right  = rect.right - kCloseMarginWidth;
		itsCloseRect.left   = itsCloseRect.right - itsCloseImage->GetWidth();
		}
	else if (itsEdge == kLeft)
		{
		itsCloseRect.top    = rect.top + kCloseMarginWidth;
		itsCloseRect.bottom = itsCloseRect.top + itsCloseImage->GetHeight();
		itsCloseRect.left   = rect.xcenter() - itsCloseImage->GetWidth()/2;
		itsCloseRect.right  = itsCloseRect.left + itsCloseImage->GetWidth();
		}
	else	// itsEdge == kRight
		{
		itsCloseRect.bottom = rect.bottom - kCloseMarginWidth;
		itsCloseRect.top    = itsCloseRect.bottom - itsCloseImage->GetHeight();
		itsCloseRect.left   = rect.xcenter() - itsCloseImage->GetWidth()/2;
		itsCloseRect.right  = itsCloseRect.left + itsCloseImage->GetWidth();
		}

	if (itsClosePushedFlag)
		{
		p.Image(*itsClosePushedImage, itsClosePushedImage->GetBounds(), itsCloseRect);
		}
	else
		{
		p.Image(*itsCloseImage, itsCloseImage->GetBounds(), itsCloseRect);
		}
}
void
JXTextCheckbox::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	const JRect bounds  = GetBounds();
	const JCoordinate y = bounds.ycenter();

	// draw button

	const JRect boxRect(y - kBoxHalfHeight, kMarginWidth,
						y + kBoxHalfHeight, kMarginWidth + kBoxHeight);
	const JBoolean drawChecked = DrawChecked();
	const JBoolean isActive    = IsActive();
	if (drawChecked && isActive)
		{
		JXDrawDownFrame(p, boxRect, kJXDefaultBorderWidth, kJTrue, itsPushedColor);
		}
	else if (isActive)
		{
		JXDrawUpFrame(p, boxRect, kJXDefaultBorderWidth, kJTrue, itsNormalColor);
		}
	else
		{
		p.SetFilling(kJTrue);
		if (drawChecked)
			{
			p.SetPenColor(itsPushedColor);
			}
		else
			{
			p.SetPenColor(itsNormalColor);
			}
		p.JPainter::Rect(boxRect);
		p.SetFilling(kJFalse);

		p.SetLineWidth(kJXDefaultBorderWidth);
		p.SetPenColor((GetColormap())->GetInactiveLabelColor());
		p.RectInside(boxRect);
		}

	// draw text

	JRect textRect  = bounds;
	textRect.left  += 2*kMarginWidth + kBoxHeight;
	p.SetFont(itsFontName, itsFontSize, itsFontStyle);
	p.String(textRect.left, textRect.top, itsLabel, itsULIndex,
			 textRect.width(), JPainter::kHAlignLeft,
			 textRect.height(), JPainter::kVAlignCenter);
}
void
JX3DWidget::DrawBorder
	(
	JXWindowPainter&	p,
	const JRect&		frame
	)
{
	const JSize borderWidth = GetBorderWidth();
	if (itsShowFocusFlag && HasFocus() && borderWidth > 0)
		{
		p.SetLineWidth(borderWidth);
		p.SetPenColor((p.GetColormap())->GetWhiteColor());
		p.RectInside(frame);
		}
	else
		{
		JXDrawDownFrame(p, frame, borderWidth);
		}
}
Example #9
0
void
Widget::Draw
	(
	JXWindowPainter& p, 
	const JRect&     rect
	)
{
	JXColormap* cmap = GetColormap();

	// This is where everything happens
	// See JPainter.h for available functions

	p.SetPenColor(cmap->GetGreenColor());
	p.Rect(10, 10, 50, 50);
	
	p.SetFilling(kJTrue);
	p.SetPenColor(cmap->GetBlueColor());
	p.Rect(10, 70, 50, 50);
}
void
ScrollingWidget::Draw
	(
	JXWindowPainter& p, 
	const JRect& rect
	)
{
	JXColormap* cmap = GetColormap();

	// Drawing goes here
	// See JPainter.h for available functions
	
	p.SetPenColor(cmap->GetGreenColor());
	p.Rect(10, 10, 50, 50);
	
	p.SetFilling(kJTrue);
	p.SetPenColor(cmap->GetBlueColor());
	p.Rect(10, 70, 50, 50);
}
void
JXImageWidget::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	if (itsImage != NULL)
		{
		p.Image(*itsImage, itsImage->GetBounds(), GetBounds());
		}
}
void
CBCommandTable::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	JXEditTable::Draw(p, rect);

	if (itsDNDRowIndex > 0)
		{
		p.ResetClipRect();

		const JSize origLineWidth = p.GetLineWidth();
		p.SetLineWidth(3);

		const JRect b = GetBounds();
		if (RowIndexValid(itsDNDRowIndex))
			{
			const JRect r = GetCellRect(JPoint(1, itsDNDRowIndex));
			p.Line(b.left, r.top, b.right, r.top);
			}
		else
			{
			const JRect r = GetCellRect(JPoint(1, GetRowCount()));
			p.Line(b.left, r.bottom, b.right, r.bottom);
			}

		p.SetLineWidth(origLineWidth);
		}
}
Example #13
0
void
JXVertPartition::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	p.SetPenColor((p.GetColormap())->GetGray60Color());

	const JRect ap       = GetAperture();
	const JCoordinate x1 = ap.left+1;
	const JCoordinate x2 = ap.right-2;

	const JSize compartmentCount = GetCompartmentCount();
	JCoordinate y = 0;
	for (JIndex i=1; i<compartmentCount; i++)
		{
		y += GetCompartmentSize(i);
		p.Line(x1, y+1, x2, y+1);
		p.Line(x1, y+3, x2, y+3);
		y += kDragRegionSize;
		}
}
void
JXHorizPartition::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	p.SetPenColor((p.GetColormap())->GetGray60Color());

	const JRect ap       = GetAperture();
	const JCoordinate y1 = ap.top+1;
	const JCoordinate y2 = ap.bottom-2;

	const JSize compartmentCount = GetCompartmentCount();
	JCoordinate x = 0;
	for (JIndex i=1; i<compartmentCount; i++)
		{
		x += GetCompartmentSize(i);
		p.Line(x+1, y1, x+1, y2);
		p.Line(x+3, y1, x+3, y2);
		x += kDragRegionSize;
		}
}
void
ClipboardWidget::Draw
	(
	JXWindowPainter& p,
	const JRect&     rect
	)
{
	// We need the colormap in order to specify colors.
	JXColormap* cmap = GetColormap();

	// This is where everything happens
	// See JPainter.h for available functions

	// This sets the color of the pen.
	p.SetPenColor(cmap->GetCyanColor());

	// This draws our rectangle.
	p.Rect(10, 10, 150, 50);

	// This draws itsText.
	p.String(20,20,itsText,
				130, JPainter::kHAlignCenter,
				30, JPainter::kVAlignCenter);
}
void
JXInputField::DrawBorder
	(
	JXWindowPainter&	p,
	const JRect&		frame
	)
{
	if (itsTable != NULL)
		{
		if (IsDNDTarget())
			{
			p.SetPenColor((p.GetColormap())->GetDefaultDNDBorderColor());
			}
		else
			{
			p.SetPenColor((GetColormap())->GetBlackColor());
			}
		p.JPainter::Rect(frame);
		}
	else
		{
		JXTEBase::DrawBorder(p, frame);
		}
}
void
JXExprEditor::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	// adjust the origin so the expression is centered in Bounds

	JPoint delta;
	GetDrawingOffset(&delta);
	p.ShiftOrigin(delta);

	// draw the function

	EIPDraw(p);
}
void
JXDocktab::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	const JColormap* cmap = p.GetColormap();

	// drag region

	JXWindow* w = GetWindow();
	JXWindow* focusWindow;

	JXDockWidget* dock;
	if (w->GetDockWidget(&dock) &&
		(dock->GetDockDirector())->GetFocusWindow(&focusWindow) &&
		focusWindow == w)
		{
		p.SetPenColor(itsFocusColor);
		p.SetFilling(kJTrue);
		p.JPainter::Rect(rect);
		p.SetPenColor((GetColormap())->GetBlackColor());
		p.SetFilling(kJFalse);

		p.SetPenColor(cmap->GetWhiteColor());
		}
	else
		{
		p.SetPenColor(cmap->GetGrayColor(60));
		}

	const JRect ap       = GetAperture();
	const JCoordinate y1 = ap.top + 1;
	const JCoordinate y2 = ap.bottom - 2;

	p.Line(3, y1, 3, y2);
	p.Line(5, y1, 5, y2);
}
Example #19
0
void
UndoWidget::Draw
	(
	JXWindowPainter& p,
	const JRect&     rect
	)
{
	// Set pen color
	p.SetPenColor((GetColormap())->GetBlackColor());

	// Find out how many points there are
	// There are count/2 lines
	JSize count = itsPoints->GetElementCount();

	// Loop through the points by twos
	for (JSize i = 1; i <= count; i += 2)
		{
		// We need to specify that this is a JPainter function because
		// JXWindowPainter has this function in a different form
		p.JPainter::Line(itsPoints->GetElement(i), itsPoints->GetElement(i+1));
		}
}
void
JXColorWheel::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	JXColormap* colormap    = GetColormap();
	const JColorIndex black = colormap->GetBlackColor();

	const JRect bounds       = GetBoundsGlobal();
	const JCoordinate max    = JMin(bounds.height(), bounds.width() - kSliderWidth - kSliderMargin);
	const JCoordinate size   = max - 2*kWheelMargin - 1;
	const JCoordinate center = size/2 + kWheelMargin;
	if (itsImage == NULL || itsImage->GetWidth() != max || itsColor.brightness != itsLastDrawBrightness)
		{
		p.SetFilling(kJTrue);
		p.SetPenColor(black);
		p.Ellipse(kWheelMargin, kWheelMargin, size, size);
		p.SetFilling(kJFalse);

		JRect r  = bounds;
		r.bottom = r.top  + max;
		r.right  = r.left + max;

		jdelete itsImage;
		itsImage = jnew JXImage(GetDisplay(), p.GetDrawable(), r);
		assert( itsImage != NULL );

		itsLastDrawBrightness = itsColor.brightness;
		for (JCoordinate x=0; x<max; x++)
			{
			const JCoordinate dx = - x + center;

			for (JCoordinate y=0; y<max; y++)
				{
				if (itsImage->GetColor(x,y) == black)
					{
					const JCoordinate dy = y - center;
					const JFloat r = sqrt(dx*dx + dy*dy) / center;
					const JFloat a = 0.5 + atan2(dy, dx) / (2.0 * kJPi);

					JHSB color(JRound(a * kJMaxHSBValue), JRound(r * kJMaxHSBValue), itsLastDrawBrightness);
					itsImage->SetColor(x,y, colormap->JColormap::GetColor(color));
					}
				}
			}

		itsImage->ConvertToRemoteStorage();
		}

	p.JPainter::Image(*itsImage, itsImage->GetBounds(), 0,0);

	const JFloat r = (itsColor.saturation / kJMaxHSBValueF) * size/2;
	const JFloat a = ((itsColor.hue / kJMaxHSBValueF) - 0.5) * 2.0 * kJPi;

	const JCoordinate x = center - JRound(r * cos(a));
	const JCoordinate y = center + JRound(r * sin(a));

	JRect mark(y-kWheelMargin, x-kWheelMargin, y+kWheelMargin+1, x+kWheelMargin+1);

	p.SetPenColor(colormap->GetWhiteColor());
	p.SetFilling(kJTrue);
	p.JPainter::Rect(mark);
	p.SetFilling(kJFalse);
	p.SetPenColor(black);
	p.JPainter::Rect(mark);
}
void
JXTextMenuTable::TableDrawCell
	(
	JPainter&		p,
	const JPoint&	cell,
	const JRect&	origRect
	)
{
	JRect rect = AdjustRectForSeparator(cell.y, origRect);

	if (cell.x == kCheckboxColumnIndex)
		{
		rect.left += kHilightBorderWidth;
		DrawCheckbox(p, cell.y, rect);
		}

	else if (cell.x == kImageColumnIndex)
		{
		const JXImage* image;
		if (itsTextMenuData->GetImage(cell.y, &image))
			{
			p.Image(*image, image->GetBounds(), rect);
			}
		}

	else if (cell.x == kTextColumnIndex)
		{
		JIndex ulIndex;
		JFontID id;
		JSize size;
		JFontStyle style;
		const JString& text =
			itsTextMenuData->GetText(cell.y, &ulIndex, &id, &size, &style);

		if (!itsTextMenuData->IsEnabled(cell.y))
			{
			style.color = (GetColormap())->GetInactiveLabelColor();
			}
		p.SetFont(id, size, style);

		rect.left += kHMarginWidth;

		JXWindowPainter* xp = dynamic_cast<JXWindowPainter*>(&p);
		assert( xp != NULL );
		xp->String(rect.left, rect.top, text, ulIndex,
				   rect.width(), JPainter::kHAlignLeft,
				   rect.height(), JPainter::kVAlignCenter);
		}

	else if (cell.x == kSubmenuColumnIndex && itsTextMenuData->HasSubmenu(cell.y))
		{
		rect.right -= kHilightBorderWidth;
		rect.left   = rect.right - JXMenuTable::kSubmenuColWidth;
		DrawSubmenuIndicator(p, cell.y, rect,
							 JConvertToBoolean(((JIndex) cell.y) == itsHilightRow));
		}

	else if (cell.x == kSubmenuColumnIndex)
		{
		const JString* nmShortcut;
		JFontID id;
		JSize size;
		JFontStyle style;
		if (itsTextMenuData->GetNMShortcut(cell.y, &nmShortcut, &id, &size, &style))
			{
			if (!itsTextMenuData->IsEnabled(cell.y))
				{
				style.color = (GetColormap())->GetInactiveLabelColor();
				}
			p.SetFont(id, size, style);

			rect.left  += kHNMSMarginWidth;
			rect.right -= kHilightBorderWidth;
			p.String(rect, *nmShortcut, JPainter::kHAlignLeft, JPainter::kVAlignCenter);
			}
		}
}
void
JXTabGroup::DrawTabBorder
	(
	JXWindowPainter&	p,
	const JRect&		rect,
	const JBoolean		isSelected
	)
{
	JXDrawUpFrame(p, rect, kBorderWidth);

	const JColormap* cmap = p.GetColormap();
	if (itsEdge == kTop)
		{
		p.SetPenColor(cmap->GetDefaultBackColor());
		p.JPainter::Point(rect.topLeft());
		p.JPainter::Point(rect.topRight() + JPoint(-1,0));
		p.JPainter::Point(rect.topRight() + JPoint(-2,0));
		p.JPainter::Point(rect.topRight() + JPoint(-1,1));
		p.JPainter::Point(rect.topRight() + JPoint(-1,2));
		p.SetPenColor(cmap->Get3DLightColor());
		p.JPainter::Point(rect.topLeft() + JPoint(kBorderWidth, kBorderWidth));
		p.SetPenColor(cmap->Get3DShadeColor());
		p.JPainter::Point(rect.topRight() + JPoint(-kBorderWidth-1, kBorderWidth));

		if (isSelected)
			{
			JRect r(rect.bottom - kBorderWidth, rect.left  + kBorderWidth,
					rect.bottom,                rect.right - kBorderWidth);
			p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
			p.JPainter::Rect(r);
			p.JPainter::Point(rect.topLeft() + JPoint(-1,kSelMargin+kBorderWidth));
			p.SetPenColor(cmap->Get3DLightColor());
			p.JPainter::Point(rect.bottomLeft()  + JPoint(1,-1));
			p.JPainter::Point(rect.bottomRight() + JPoint(-2,-1));
			p.JPainter::Point(rect.bottomRight() + JPoint(-1,-2));
			p.JPainter::Point(rect.bottomRight() + JPoint(-1,-1));
			}
		}

	else if (itsEdge == kLeft)
		{
		p.SetPenColor(cmap->GetDefaultBackColor());
		p.JPainter::Point(rect.topLeft());
		p.JPainter::Point(rect.bottomLeft() + JPoint(0,-1));
		p.JPainter::Point(rect.bottomLeft() + JPoint(0,-2));
		p.JPainter::Point(rect.bottomLeft() + JPoint(1,-1));
		p.JPainter::Point(rect.bottomLeft() + JPoint(2,-1));
		p.SetPenColor(cmap->Get3DLightColor());
		p.JPainter::Point(rect.topLeft() + JPoint(kBorderWidth, kBorderWidth));
		p.SetPenColor(cmap->Get3DShadeColor());
		p.JPainter::Point(rect.bottomLeft() + JPoint(kBorderWidth, -kBorderWidth-1));

		if (isSelected)
			{
			JRect r(rect.top    + kBorderWidth, rect.right - kBorderWidth,
					rect.bottom - kBorderWidth, rect.right);
			p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
			p.JPainter::Rect(r);
			p.JPainter::Point(rect.topLeft() + JPoint(kSelMargin+kBorderWidth,-1));
			p.SetPenColor(cmap->Get3DLightColor());
			p.JPainter::Point(rect.topRight() + JPoint(-1,1));
			if (rect.bottom < (GetAperture()).bottom)
				{
				p.JPainter::Point(rect.bottomRight() + JPoint(-1,-1));
				p.JPainter::Point(rect.bottomRight() + JPoint(-2,-1));
				p.JPainter::Point(rect.bottomRight() + JPoint(-1,-2));
				}
			}
		}

	else if (itsEdge == kBottom)
		{
		p.SetPenColor(cmap->GetDefaultBackColor());
		p.JPainter::Point(rect.bottomLeft()  + JPoint(0,-1));
		p.JPainter::Point(rect.bottomLeft()  + JPoint(0,-2));
		p.JPainter::Point(rect.bottomLeft()  + JPoint(1,-1));
		p.JPainter::Point(rect.bottomLeft()  + JPoint(2,-1));
		p.JPainter::Point(rect.bottomRight() + JPoint(-1,-1));
		p.SetPenColor(cmap->Get3DLightColor());
		p.JPainter::Point(rect.bottomLeft() + JPoint(kBorderWidth, -kBorderWidth-1));
		p.SetPenColor(cmap->Get3DShadeColor());
		p.JPainter::Point(rect.bottomRight() + JPoint(-kBorderWidth-1, -kBorderWidth-1));

		if (isSelected)
			{
			JRect r(rect.top,                rect.left  + kBorderWidth,
					rect.top + kBorderWidth, rect.right - kBorderWidth);
			p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
			p.JPainter::Rect(r);
			p.SetPenColor(cmap->Get3DShadeColor());
			if (rect.left > (GetAperture()).left)
				{
				p.JPainter::Point(rect.topLeft());
				}
			p.JPainter::Point(rect.topRight() + JPoint(-1,0));
			p.JPainter::Point(rect.topRight() + JPoint(-2,0));
			p.JPainter::Point(rect.topRight() + JPoint(-2,1));
			}
		}

	else if (itsEdge == kRight)
		{
		p.SetPenColor(cmap->GetDefaultBackColor());
		p.JPainter::Point(rect.topRight() + JPoint(-1,0));
		p.JPainter::Point(rect.topRight() + JPoint(-2,0));
		p.JPainter::Point(rect.topRight() + JPoint(-1,1));
		p.JPainter::Point(rect.topRight() + JPoint(-1,2));
		p.JPainter::Point(rect.bottomRight() + JPoint(-1,-1));
		p.SetPenColor(cmap->Get3DLightColor());
		p.JPainter::Point(rect.topRight() + JPoint(-kBorderWidth-1, kBorderWidth));
		p.SetPenColor(cmap->Get3DShadeColor());
		p.JPainter::Point(rect.bottomRight() + JPoint(-kBorderWidth-1, -kBorderWidth-1));

		if (isSelected)
			{
			JRect r(rect.top    + kBorderWidth, rect.left,
					rect.bottom - kBorderWidth, rect.left + kBorderWidth);
			p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
			p.JPainter::Rect(r);
			p.SetPenColor(cmap->Get3DShadeColor());
			if (rect.top > (GetAperture()).top)
				{
				p.JPainter::Point(rect.topLeft());
				}
			p.JPainter::Point(rect.bottomLeft() + JPoint(0,-1));
			p.JPainter::Point(rect.bottomLeft() + JPoint(0,-2));
			p.JPainter::Point(rect.bottomLeft() + JPoint(1,-2));
			}
		}
}
void
JXTabGroup::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	const JRect ap = GetAperture();

	p.SetFont(itsFontName, itsFontSize, itsFontStyle);
	const JSize lineHeight = p.GetLineHeight();
	const JSize tabHeight  = 2*(kBorderWidth + kTextMargin) + lineHeight;

	JIndex selIndex;
	JRect selRect;
	const JBoolean hasSelection = itsCardFile->GetCurrentCardIndex(&selIndex);

	itsTabRects->RemoveAll();
	itsCanScrollUpFlag   = JI2B(itsFirstDrawIndex > 1);
	itsCanScrollDownFlag = kJFalse;

	const JCoordinate scrollArrowWidth = 2*(kArrowWidth + kBorderWidth);

	const JSize count = itsTitles->GetElementCount();
	itsLastDrawIndex  = JMax(count, itsFirstDrawIndex);

	const JColormap* cmap = p.GetColormap();
	if (itsEdge == kTop)
		{
		JRect r(ap.top + kSelMargin,             ap.left + kSelMargin,
				ap.top + kSelMargin + tabHeight, ap.left + kSelMargin);

		for (JIndex i=itsFirstDrawIndex; i<=count; i++)
			{
			const JString* title = itsTitles->NthElement(i);
			const JBoolean isSel = JI2B(hasSelection && i == selIndex);
			const TabInfo info   = itsTabInfoList->GetElement(i);

			r.right += 2*kBorderWidth + info.preMargin +info.postMargin + p.GetStringWidth(*title);
			if (info.closable)
				{
				r.right += kCloseMarginWidth + itsCloseImage->GetWidth();
				}
			JPoint titlePt(r.left + kBorderWidth + info.preMargin,
						   r.top  + kBorderWidth + kTextMargin);
			if (isSel)
				{
//				titlePt.y -= kSelMargin;
				r.top     -= kSelMargin;
				r.Expand(kSelMargin, 0);

				selRect = r;
				}

			if (isSel)
				{
				p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
				p.SetFilling(kJTrue);
				p.JPainter::Rect(r);
				p.SetFilling(kJFalse);
				}
			else
				{
				DrawTabBorder(p, r, kJFalse);
				}
			p.JPainter::String(titlePt, *title);

			itsTabRects->AppendElement(r);
			if (isSel)
				{
				r.top += kSelMargin;
				r.Shrink(kSelMargin, 0);
				}

			r.Shrink(kBorderWidth, kBorderWidth);
			DrawTab(i, p, r, itsEdge);
			DrawCloseButton(i, p, r);
			r.Expand(kBorderWidth, kBorderWidth);

			if (r.right >= ap.right - scrollArrowWidth)
				{
				if (itsFirstDrawIndex == 1 && i == count && r.right <= ap.right)
					{
					break;
					}
				itsCanScrollDownFlag = JI2B( itsFirstDrawIndex < count );
				itsLastDrawIndex     = i;
				if (r.right > ap.right - scrollArrowWidth && i > itsFirstDrawIndex)
					{
					itsLastDrawIndex--;
					}
				break;
				}

			r.left = r.right;
			}
		}

	else if (itsEdge == kLeft)
		{
		JRect r(ap.bottom - kSelMargin, ap.left + kSelMargin,
				ap.bottom - kSelMargin, ap.left + kSelMargin + tabHeight);

		for (JIndex i=itsFirstDrawIndex; i<=count; i++)
			{
			const JString* title = itsTitles->NthElement(i);
			const JBoolean isSel = JI2B(hasSelection && i == selIndex);
			const TabInfo info   = itsTabInfoList->GetElement(i);

			r.top -= 2*kBorderWidth + info.preMargin + info.postMargin + p.GetStringWidth(*title);
			if (info.closable)
				{
				r.top -= kCloseMarginWidth + itsCloseImage->GetWidth();
				}
			JPoint titlePt(r.left   + kBorderWidth + kTextMargin,
						   r.bottom - kBorderWidth - info.preMargin);
			if (isSel)
				{
//				titlePt.x -= kSelMargin;
				r.left    -= kSelMargin;
				r.Expand(0, kSelMargin);

				selRect = r;
				}

			if (isSel)
				{
				p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
				p.SetFilling(kJTrue);
				p.JPainter::Rect(r);
				p.SetFilling(kJFalse);
				}
			else
				{
				DrawTabBorder(p, r, kJFalse);
				}
			p.JPainter::String(90, titlePt, *title);

			itsTabRects->AppendElement(r);
			if (isSel)
				{
				r.left += kSelMargin;
				r.Shrink(0, kSelMargin);
				}

			r.Shrink(kBorderWidth, kBorderWidth);
			DrawTab(i, p, r, itsEdge);
			DrawCloseButton(i, p, r);
			r.Expand(kBorderWidth, kBorderWidth);

			if (r.top <= ap.top + scrollArrowWidth)
				{
				if (itsFirstDrawIndex == 1 && i == count && r.top >= ap.top)
					{
					break;
					}
				itsCanScrollDownFlag = JI2B( itsFirstDrawIndex < count );
				itsLastDrawIndex     = i;
				if (r.top < ap.top + scrollArrowWidth && i > itsFirstDrawIndex)
					{
					itsLastDrawIndex--;
					}
				break;
				}

			r.bottom = r.top;
			}
		}

	else if (itsEdge == kBottom)
		{
		JRect r(ap.bottom - kSelMargin - tabHeight, ap.left + kSelMargin,
				ap.bottom - kSelMargin,             ap.left + kSelMargin);

		for (JIndex i=itsFirstDrawIndex; i<=count; i++)
			{
			const JString* title = itsTitles->NthElement(i);
			const JBoolean isSel = JI2B(hasSelection && i == selIndex);
			const TabInfo info   = itsTabInfoList->GetElement(i);

			r.right += 2*kBorderWidth + info.preMargin + info.postMargin + p.GetStringWidth(*title);
			if (info.closable)
				{
				r.right += kCloseMarginWidth + itsCloseImage->GetWidth();
				}
			JPoint titlePt(r.left + kBorderWidth + info.preMargin,
						   r.top  + kBorderWidth + kTextMargin);
			if (isSel)
				{
//				titlePt.y += kSelMargin;
				r.bottom  += kSelMargin;
				r.Expand(kSelMargin, 0);

				selRect = r;
				}

			if (isSel)
				{
				p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
				p.SetFilling(kJTrue);
				p.JPainter::Rect(r);
				p.SetFilling(kJFalse);
				}
			else
				{
				DrawTabBorder(p, r, kJFalse);
				}
			p.JPainter::String(titlePt, *title);

			itsTabRects->AppendElement(r);
			if (isSel)
				{
				r.bottom -= kSelMargin;
				r.Shrink(kSelMargin, 0);
				}

			r.Shrink(kBorderWidth, kBorderWidth);
			DrawTab(i, p, r, itsEdge);
			DrawCloseButton(i, p, r);
			r.Expand(kBorderWidth, kBorderWidth);

			if (r.right >= ap.right - scrollArrowWidth)
				{
				if (itsFirstDrawIndex == 1 && i == count && r.right <= ap.right)
					{
					break;
					}
				itsCanScrollDownFlag = JI2B( itsFirstDrawIndex < count );
				itsLastDrawIndex     = i;
				if (r.right > ap.right - scrollArrowWidth && i > itsFirstDrawIndex)
					{
					itsLastDrawIndex--;
					}
				break;
				}

			r.left = r.right;
			}
		}

	else if (itsEdge == kRight)
		{
		JRect r(ap.top + kSelMargin, ap.right - kSelMargin - tabHeight,
				ap.top + kSelMargin, ap.right - kSelMargin);

		for (JIndex i=itsFirstDrawIndex; i<=count; i++)
			{
			const JString* title = itsTitles->NthElement(i);
			const JBoolean isSel = JI2B(hasSelection && i == selIndex);
			const TabInfo info   = itsTabInfoList->GetElement(i);

			r.bottom += 2*kBorderWidth + info.preMargin + info.postMargin + p.GetStringWidth(*title);
			if (info.closable)
				{
				r.bottom += kCloseMarginWidth + itsCloseImage->GetWidth();
				}
			JPoint titlePt(r.right - kBorderWidth - kTextMargin,
						   r.top   + kBorderWidth + info.preMargin);
			if (isSel)
				{
//				titlePt.x += kSelMargin;
				r.right   += kSelMargin;
				r.Expand(0, kSelMargin);

				selRect = r;
				}

			if (isSel)
				{
				p.SetPenColor(cmap->GetGrayColor(kSelGrayPercentage));
				p.SetFilling(kJTrue);
				p.JPainter::Rect(r);
				p.SetFilling(kJFalse);
				}
			else
				{
				DrawTabBorder(p, r, kJFalse);
				}
			p.JPainter::String(-90, titlePt, *title);

			itsTabRects->AppendElement(r);
			if (isSel)
				{
				r.right -= kSelMargin;
				r.Shrink(0, kSelMargin);
				}

			r.Shrink(kBorderWidth, kBorderWidth);
			DrawTab(i, p, r, itsEdge);
			DrawCloseButton(i, p, r);
			r.Expand(kBorderWidth, kBorderWidth);

			if (r.bottom >= ap.bottom - scrollArrowWidth)
				{
				if (itsFirstDrawIndex == 1 && i == count && r.bottom <= ap.bottom)
					{
					break;
					}
				itsCanScrollDownFlag = JI2B( itsFirstDrawIndex < count );
				itsLastDrawIndex     = i;
				if (r.bottom > ap.bottom - scrollArrowWidth && i > itsFirstDrawIndex)
					{
					itsLastDrawIndex--;
					}
				break;
				}

			r.top = r.bottom;
			}
		}

	JRect r = itsCardFile->GetFrame();
	r.Expand(kBorderWidth, kBorderWidth);
	JXDrawUpFrame(p, r, kBorderWidth);

	if (!selRect.IsEmpty())
		{
		DrawTabBorder(p, selRect, kJTrue);
		}

	DrawScrollButtons(p, lineHeight);
}
void
JXTabGroup::DrawScrollButtons
	(
	JXWindowPainter&	p,
	const JCoordinate	lineHeight
	)
{
	itsScrollUpRect = itsScrollDownRect = JRect(0,0,0,0);
	if (!itsCanScrollUpFlag && !itsCanScrollDownFlag)
		{
		return;
		}

	const JCoordinate w = 2*(kArrowWidth + kBorderWidth);
	const JCoordinate h = kSelMargin + kBorderWidth + 2*kTextMargin + lineHeight;

	const JRect ap        = GetAperture();
	const JColormap* cmap = p.GetColormap();
	if (itsEdge == kTop)
		{
		JRect r(ap.top,     ap.right - w,
				ap.top + h, ap.right);

		p.SetPenColor(cmap->GetDefaultBackColor());
		p.SetFilling(kJTrue);
		p.JPainter::Rect(r);
		p.SetFilling(kJFalse);

		r.Shrink(kBorderWidth, 0);
		r.top = r.bottom = r.ycenter();
		r.top    -= kArrowWidth/2;
		r.bottom += kArrowWidth/2 + kArrowWidth%2;

		r.right = r.left + kArrowWidth;
		if (itsCanScrollUpFlag && itsScrollUpPushedFlag)
			{
			JXDrawDownArrowLeft(p, r, kBorderWidth);
			}
		else if (itsCanScrollUpFlag)
			{
			JXDrawUpArrowLeft(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowLeft(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollUpRect = r;

		r.left  += kArrowWidth;
		r.right += kArrowWidth;
		if (itsCanScrollDownFlag && itsScrollDownPushedFlag)
			{
			JXDrawDownArrowRight(p, r, kBorderWidth);
			}
		else if (itsCanScrollDownFlag)
			{
			JXDrawUpArrowRight(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowRight(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollDownRect = r;
		}

	else if (itsEdge == kLeft)
		{
		JRect r(ap.top,     ap.left,
				ap.top + w, ap.left + h);

		p.SetPenColor(cmap->GetDefaultBackColor());
		p.SetFilling(kJTrue);
		p.JPainter::Rect(r);
		p.SetFilling(kJFalse);

		r.Shrink(0, kBorderWidth);
		r.left = r.right = r.xcenter();
		r.left  -= kArrowWidth/2;
		r.right += kArrowWidth/2 + kArrowWidth%2;

		r.bottom = r.top + kArrowWidth;
		if (itsCanScrollDownFlag && itsScrollDownPushedFlag)
			{
			JXDrawDownArrowUp(p, r, kBorderWidth);
			}
		else if (itsCanScrollDownFlag)
			{
			JXDrawUpArrowUp(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowUp(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollDownRect = r;

		r.top    += kArrowWidth;
		r.bottom += kArrowWidth;
		if (itsCanScrollUpFlag && itsScrollUpPushedFlag)
			{
			JXDrawDownArrowDown(p, r, kBorderWidth);
			}
		else if (itsCanScrollUpFlag)
			{
			JXDrawUpArrowDown(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowDown(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollUpRect = r;
		}

	else if (itsEdge == kBottom)
		{
		JRect r(ap.bottom - h, ap.right - w,
				ap.bottom,     ap.right);

		p.SetPenColor(cmap->GetDefaultBackColor());
		p.SetFilling(kJTrue);
		p.JPainter::Rect(r);
		p.SetFilling(kJFalse);

		r.Shrink(kBorderWidth, 0);
		r.top = r.bottom = r.ycenter();
		r.top    -= kArrowWidth/2;
		r.bottom += kArrowWidth/2 + kArrowWidth%2;

		r.right = r.left + kArrowWidth;
		if (itsCanScrollUpFlag && itsScrollUpPushedFlag)
			{
			JXDrawDownArrowLeft(p, r, kBorderWidth);
			}
		else if (itsCanScrollUpFlag)
			{
			JXDrawUpArrowLeft(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowLeft(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollUpRect = r;

		r.left  += kArrowWidth;
		r.right += kArrowWidth;
		if (itsCanScrollDownFlag && itsScrollDownPushedFlag)
			{
			JXDrawDownArrowRight(p, r, kBorderWidth);
			}
		else if (itsCanScrollDownFlag)
			{
			JXDrawUpArrowRight(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowRight(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollDownRect = r;
		}

	else if (itsEdge == kRight)
		{
		JRect r(ap.bottom - w, ap.right - h,
				ap.bottom,     ap.right);

		p.SetPenColor(cmap->GetDefaultBackColor());
		p.SetFilling(kJTrue);
		p.JPainter::Rect(r);
		p.SetFilling(kJFalse);

		r.Shrink(0, kBorderWidth);
		r.left = r.right = r.xcenter();
		r.left  -= kArrowWidth/2;
		r.right += kArrowWidth/2 + kArrowWidth%2;

		r.bottom = r.top + kArrowWidth;
		if (itsCanScrollUpFlag && itsScrollUpPushedFlag)
			{
			JXDrawDownArrowUp(p, r, kBorderWidth);
			}
		else if (itsCanScrollUpFlag)
			{
			JXDrawUpArrowUp(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowUp(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollUpRect = r;

		r.top    += kArrowWidth;
		r.bottom += kArrowWidth;
		if (itsCanScrollDownFlag && itsScrollDownPushedFlag)
			{
			JXDrawDownArrowDown(p, r, kBorderWidth);
			}
		else if (itsCanScrollDownFlag)
			{
			JXDrawUpArrowDown(p, r, kBorderWidth);
			}
		else
			{
			JXFillArrowDown(p, r, cmap->GetInactiveLabelColor());
			}
		itsScrollDownRect = r;
		}
}