/// レイアウト要素のBoundRelative領域の変更を試みる /// @param layoutElement レイアウト要素 /// @param target 変更箇所 /// @param value 変更値 /// @param[out] changed 変更後、制約を満たす形に訂正されたBoundRelative領域 /// @return 試行結果(訂正箇所) public static TryResult TryChange( LayoutElement layoutElement, Names target, double value, out RelativeLTRB changed) { // 準備 var original = BoundRelativeInputCorrector.GetOriginal(layoutElement); // 訂正 switch (target) { case Names.Left: case Names.Top: { return(BoundRelativeInputCorrector.TryChangeLow(original, target, value, Constants.MinimumBoundRelativeSize, out changed)); } case Names.Right: case Names.Bottom: { return(BoundRelativeInputCorrector.TryChangeHigh(original, target, value, Constants.MinimumBoundRelativeSize, out changed)); } default: Debug.Fail("switch"); throw new System.ArgumentException(); } }
//================================================================= // 訂正 //================================================================= /// BoundRelative*の値が小さい方の位置要素(Left/Top)の変更を試みる /// @param original 変更前のBoundRelativeLTRB /// @param target 変更箇所 /// @param value 変更値 /// @param sizeLowerBound 訂正後のサイズ要素(Width/Height)の最小値 /// @param[out] changed 変更後、制約を満たす形に訂正されたBoundRelativeLTRB /// @return 試行結果(訂正箇所) private static TryResult TryChangeLow(RelativeLTRB original, Names target, double value, double sizeLowerBound, out RelativeLTRB changed) { Debug.Assert(target == Names.Left || target == Names.Top); // 準備 var onX = (target == Names.Left); var low = value; var high = onX ? original.Right : original.Bottom; var result = TryResult.NothingChanged; // highのチェック /// @todo(me) 浮動小数点数の比較 Debug.Assert(0.0 + sizeLowerBound <= high && high <= 1.0); // 上限・下限の補正 /// @attention 浮動小数点数の比較 if (low < 0.0) { low = 0.0; result |= TryResult.TargetChanged; } else if (1.0 - sizeLowerBound < low) { low = 1.0 - sizeLowerBound; result |= TryResult.TargetChanged; } // lowが大きすぎる場合、highを増やして最小幅を確保 if (high < low + sizeLowerBound) { high = low + sizeLowerBound; result |= TryResult.DependentChanged; } // 出力 changed = onX ? new RelativeLTRB(low, original.Top, high, original.Bottom) : new RelativeLTRB(original.Left, low, original.Right, high); return(result); }
/// BoundRelative*の値が大きい方の位置要素(Right/Bottom)の変更を試みる /// @param original 変更前のBoundRelativeLTRB /// @param target 変更箇所 /// @param value 変更値 /// @param sizeLowerBound 訂正後のサイズ要素(Width/Height)の最小値 /// @param[out] changed 変更後、制約を満たす形に訂正されたBoundRelativeLTRB /// @return 試行結果(訂正箇所) public static TryResult TryChangeHigh(RelativeLTRB original, Names target, double value, double sizeLowerBound, out RelativeLTRB changed) { Debug.Assert(target == Names.Right || target == Names.Bottom); // 準備 var onX = (target == Names.Right); var low = onX ? original.Left : original.Top; var high = value; var result = TryResult.NothingChanged; // lowのチェック /// @todo(me) 浮動小数点数の比較 Debug.Assert(0.0 <= low && low <= 1.0 - sizeLowerBound); // 上限・下限の補正 /// @attention 浮動小数点数の比較 if (high < 0.0 + sizeLowerBound) { high = 0.0 + sizeLowerBound; result |= TryResult.TargetChanged; } else if (1.0 < high) { high = 1.0; result |= TryResult.TargetChanged; } // lowが大きすぎる場合、lowを減らして最小幅を確保 if (high < low + sizeLowerBound) { low = high - sizeLowerBound; result |= TryResult.DependentChanged; } // 出力 changed = onX ? new RelativeLTRB(low, original.Top, high, original.Bottom) : new RelativeLTRB(original.Left, low, original.Right, high); return(result); }
/// フィールドを初期化 private void Clear() { this.target = null; this.hitMode = HitModes.Neutral; this.mouseOffset = null; this.originalLTRB = null; this.snapGuide = null; this.lastUpdateControl = 0; this.MousePoint = null; this.ShouldUpdateControl = false; }
//=================================================================== // 動作 //=================================================================== /// 開始 public void Start(LayoutElement target, HitModes hitMode, RelativePoint mousePoint, SnapGuide snapGuide) { this.target = target; this.hitMode = hitMode; this.mouseOffset = new RelativeMouseOffset(target, mousePoint); this.originalLTRB = new RelativeLTRB(target.BoundRelativeLeft, target.BoundRelativeTop, target.BoundRelativeRight, target.BoundRelativeBottom); this.snapGuide = snapGuide; this.lastUpdateControl = Environment.TickCount; this.MousePoint = mousePoint; this.ShouldUpdateControl = false; }