Foundation > グラフィック・オブジェクト > 新規グラフィック・オブジェクト・クラスの作成 > オブジェクト関数の実装
 
オブジェクト関数の実装
このexampleでは、新規クラスと必要なオーバーロード・メンバー関数を宣言するヘッダー・ファイルを作成します。
このセクションでは、shadellp.cpp ファイルに実装されている関数のコードについて説明します。
computeInvertedPalette メンバー関数
void
ShadowEllipse::computeInvertedPalette()
{
IlvPalette* newPalette = getDisplay()->getInvertedPalette(getPalette());
newPalette->lock();
if (_invertedPalette)
_invertedPalette->unLock();
_invertedPalette = newPalette;
}
メンバー関数 computeInvertedPalette は、メンバー関数 getPalette の呼び出しにより取得したパレットから反転パレットを計算します。この反転パレットを作成し、前のパレットがある場合はロック解除し、新しいパレットをロックします。
この関数は、(適切なメンバー関数をオーバーロードすることにより) 元のパレットが変更されるたびに、およびオブジェクトが最初に作成されるときに呼び出されます。
この 2 番目のパレットの作成は、多少奇妙に思われるかもしれません。メンバー関数 draw で、2 番目のパレットは、2 つの IlvDisplay 描画メンバー関数を呼び出すときのみに使われます。別のメソッドは、これらのメンバー関数を呼び出す前にメンバー関数 IlvPalette::invert を呼び出し、別の IlvPalette::invert を呼び出すことによりパレットを元の状態に戻してしまう可能性があります。Rogue Wave Views を使用した作成は、これがオブジェクトを操作する効率的な方法ではないことを示しています。パレット管理は、Rogue Wave Views によって実行される非常に効率的なタスクの 1 つです。必要なときはパレット管理を使用してください。
デストラクター
ShadowEllipse::~ShadowEllipse()
{
_invertedPalette->unLock();
}
デストラクターでは、反転したパレットをディスプレイに解放し、他のオブジェクトによって使用されない場合は削除できるようにする必要があります。
draw メンバー関数
メンバー関数 draw は、2 つの楕円を塗りつぶし、一番上の楕円ボーダーを描画します。グローバル・バウンディング矩形 (_rect) は、実際に両方の楕円を覆います。
メンバー関数 draw を下記に示します。これは、オブジェクトの描画は、IlvDisplay クラスのプリミティブ・メンバー関数にのいくつかを呼び出すだけであることを示しています。
void
ShadowEllipse::draw(IlvPort* dst, const IlvTransformer* t,
const IlvRegion* clip) const
{
// Transform the bounding rectangle ______________________________
IlvRect rect = _rect;
if (t)
t->apply(rect);
 
// Store both the display and palette ____________________________
IlvPalette* palette = getPalette();
 
// Find a correct value for thickness ____________________________
IlUShort thickness = _thickness;
if ((rect.w() <= thickness) || (rect.h() <= thickness))
thickness = IlMin(rect.w(), rect.h());
 
// Compute actual shadow rectangle _______________________________
rect.grow(-thickness, -thickness);
IlvRect shadowRect = rect;
shadowRect.translate(thickness, thickness);
 
#if defined(USE_2_PALETTES)
// Set the clipping region for both palettes _____________________
if (clip) {
palette->setClip(clip);
_invertedPalette->setClip(clip);
}
// Fill shadow Ellipse ___________________________________________
dst->fillArc(palette, shadowRect, 0., 360.);
 
// Fill inverted Ellipse _________________________________________
dst->fillArc(_invertedPalette, rect, 0., 360.);
 
// Draw ellipse __________________________________________________
dst->drawArc(palette, rect, 0., 360.);
if (clip) {
palette->setClip();
_invertedPalette->setClip();
}
#else /* !USE_2_PALETTES */
// Set the clipping region for both palettes _____________________
if (clip)
palette->setClip(clip);
 
// Fill shadow ellipse ___________________________________________
dst->fillArc(palette, shadowRect, 0., 360.);
 
// Compute inverted palette and fill inverted ellipse ____________
palette->invert();
dst->fillArc(palette, rect, 0., 360.);
palette->invert();
// Draw elliptic border __________________________________________
dst->drawArc(palette, rect, 0., 360.);
 
// Set the clipping region for both palettes _____________________
if (clip)
palette->setClip();
#endif /* !USE_2_PALETTES */
}
ここではトランスフォーマー t を使用して描画を実行する必要はありません。これはどんな変換でも幅を同じにするためです。
複雑な描画を行う場合は、clip パラメーターを使用できます (この場合は必要ありません)。この関数から返す前に、影響を受けたパレットすべてのクリッピング領域を空の領域にリセットする必要があります。
boundingBox メンバー関数
メンバー関数 boundingBox は、グローバル・バウンディング矩形を変換します。
void
ShadowEllipse::boundingBox(IlvRect& rect,
const IlvTransformer* t) const
{
rect = _rect;
if (t)
t->apply(rect);
}
メモ: 消去エラーを避けるために、バウンディング・ボックスには完全な描画が含まれていなければなりません。
contains メンバー関数
メンバー関数 contains は、2 つの楕円のうち 1 つの中に点がある場合は IlTrue を返します。すべての座標はビューの座標系を基準に指定されます。
static IlBoolean
IsPointInEllipse(const IlvPoint& p, const IlvRect& bbox)
{
if (!bbox.contains(p))
return IlFalse;
IlUInt rx = bbox.w() / 2,
ry = bbox.h() / 2;
IlUInt dx = (p.x() - bbox.centerx()) * (p.x() - bbox.centerx()),
dy = (p.y() - bbox.centery()) * (p.y() - bbox.centery()),
rrx = rx*rx,
rry = ry*ry;
return (rrx * dy + rry * dx <= rrx * rry) ?IlTrue :IlFalse;
}
IlBoolean
ShadowEllipse::contains(const IlvPoint&, const IlvPoint& tp,
const IlvTransformer* t) const
{
IlvRect rect = _rect;
if (t)
t->apply(rect);
if ((rect.w() <= _thickness) || (rect.h() <= _thickness))
return IsPointInEllipse(tp, rect);
else {
rect.grow(-_thickness, -_thickness);
IlvRect shadowRect = rect;
shadowRect.translate(_thickness, _thickness);
return (IlBoolean)(IsPointInEllipse(tp, rect) ||
IsPointInEllipse(tp, shadowRect));
}
}
contains がスタティック関数 IsPointInEllipse を呼び出しています。これは点のパラメーターが矩形パラメーターに定義された楕円の中にあるかどうかをテストします。
applyTransform メンバー関数
applyTransform メンバー関数は、トランスフォーマーをグラフィックの矩形に適用します。
void ShadowEllipse::applyTransform(const IlvTransformer* t)
{
if (t)
t->apply(_rect);
}

Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.