前回の実装では Knobを元領域を超えてドラッグすると下記のように枠線が消えてしまっていた。
これはドラッグの結果、NSRect.size が負の値をとっていた為(だから描画されない)。
Knobを元領域を超えてドラッグするとは下記のようなイメージ。
元領域を超えてドラッグすると Knobの位置が実質的に入れ替わるため、意図しない Knobの位置の処理が適用されてしまうため。例えば上記例の様に左上の Knobをドラッグした時には、当然左上の Knobの処理が手適用される。この時左上の Knob様に定義された前回のアフィン変換のパラメータが適用される。しかし元領域を超えて右下へドラッグすると、枠に対する位置が左上ではなく、右下になる。つまりここに来たら右下用のパラメータを適用しなければならない。
Sketch ではこの動作に対応する為に Knobの位置変換用の対応配列を用意して、内部的に処理対象のKnobを入れ替えている。今回は範囲の拡大縮小ができれば良いだけなので Sketch の方法はとらずにもっと簡単に実装した。
表示の時に NSRect.sizeが負なら補正してしまう。
表示の時に NSRect.sizeが負なら補正してしまう。
- (NSRect)normalizeRect:(NSRect)rect
{
NSRect rect2 = rect;
if (rect.size.width < 0) {
rect2.origin.x = rect.origin.x + rect.size.width;
rect2.size.width = -rect.size.width;
}
if (rect.size.height < 0) {
rect2.origin.y = rect.origin.y + rect.size.height;
rect2.size.height = -rect.size.height;
}
return rect2;
}
もちろんドラッグ操作が終わった後も直しておく必要がある。
すると元領域を超えたドラッグでも問題なく表示できる。