ページ

2008年4月29日火曜日

RubberBand(その13)決まった単位でリサイズ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

コマンドキーを押しながらKnobをドラッグすると決まった単位(5ドットなど)でリサイズできるようにする。



ソース:RubberBand-10.zip

コマンドキー押下の判断は NSEvent#modifierFlags でできる。

resize_by_unit = [event modifierFlags] & NSCommandKeyMask


移動量が一定のサイズ(下記コードでは _resize_unit: 初期値 5.0)を超えた時だけリサイズを起こさせる。そして移動量を強制的に一定のサイズに合わせてしまう。例えば一定のサイズを 5.0とすると、これを超える移動量の場合だけリサイズさせる。移動量が 6.2なら 1.2を切り捨てて移動量は 5.0 にする。すると 5.0ドット単位でのリサイズが可能になる。一方、5.0に満たない移動の場合は、リサイズを見送る。

   if (resize_by_unit) {
if (fabs(dx) >= _resize_unit) {
mx = fmod(dx, _resize_unit);
dx = dx - mx;
pp.x = cp.x - mx;
} else {
dx = 0.0;
}
if (fabs(dy) >= _resize_unit) {
my = fmod(dy, _resize_unit);
dy = dy - my;
pp.y = cp.y - my;
} else {
dy = 0.0;
}
} else {
pp.x = cp.x;
pp.y = cp.y;
}


ここまでは簡単にできる。厄介なのがサイズを一定の単位に合わせる処理。例えば 5.0ドット単位でリサイズする場合、直前の横幅が 321であれば、移動方向によって初回のサイズを 320 もしくは 325 に合わせたい。先の処理だけだと 316 もしくは 326 になってしまう。そこで場合分けをしてKnobの位置に応じた補正処理を追加する。

 if (resize_by_unit) {
mx = fmod(_rect.size.width, _resize_unit);
my = fmod(_rect.size.height, _resize_unit);

if (mx && fabs(dx) > 0.0) {
if (rule.x > 0) {
if (dx > 0) {
_rect.origin.x += -(_resize_unit - mx) * rule.x;
_rect.size.width += -(_resize_unit - mx) * rule.w;
} else if (dx < 0) {
_rect.origin.x += mx * rule.x;
_rect.size.width += mx * rule.w;
}
} else {
if (dx > 0) {
_rect.origin.x += -mx * rule.x;
_rect.size.width += -mx * rule.w;
} else if (dx < 0) {
_rect.origin.x += (_resize_unit - mx) * rule.x;
_rect.size.width += (_resize_unit - mx) * rule.w;
}
}
}
:
:
}


あまりうまい方法がうかばずベタなコーディングとなってしまった。コードはKnobの位置と移動方向による場合分けでサイズを補正している。RubberBandのサイズ補正はKnobの位置によってはsizeだけでなく originも変更が必要なのでややこしい。

それはともあれできた。