/// レイアウト要素のClipping領域(Fitオプションなし)の変更を試みる
        /// @param layoutElement レイアウト要素
        /// @param target 変更箇所
        /// @param value 変更値
        /// @param[out] changed 変更後、制約を満たす形に訂正されたClipping領域
        /// @return 試行結果(訂正箇所)
        public static TryResult TryChange(
            LayoutElement layoutElement, Names target, int value,
            out ClientRect changed)
        {
            Debug.Assert(layoutElement.IsWindowValid);
            Debug.Assert(!layoutElement.Fit);

            // 準備
            var original = ClippingInputCorrector.GetOriginal(layoutElement);
            var window = Utilities.GetWindowRect(layoutElement.WindowType, layoutElement.Window);

            // 訂正
            switch (target) {
              case Names.X:
              case Names.Y: {
            return ClippingInputCorrector.TryChangePosition(
            original, target, value, window,
            Constants.MinimumClippingSize, out changed);
              }
              case Names.Width:
              case Names.Height: {
            return ClippingInputCorrector.TryChangeSize(
            original, target, value, window,
            Constants.MinimumClippingSize, out changed);
              }
              default: Debug.Fail("switch"); throw new System.ArgumentException();
            }
        }
 //===================================================================
 // コンストラクタ
 //===================================================================
 /// コンストラクタ
 public ScreenCaptureRequest(LayoutElement layoutElement)
 {
     Debug.Assert(layoutElement.IsWindowValid, "Invalid Window", "ScreenCaptureRequest");
     this.Window = layoutElement.Window;
     this.ClippingX = layoutElement.ClippingXWithFit;
     this.ClippingY = layoutElement.ClippingYWithFit;
     this.ClippingWidth = layoutElement.ClippingWidthWithFit;
     this.ClippingHeight = layoutElement.ClippingHeightWithFit;
     this.ShowCursor = layoutElement.ShowCursor;
     this.ShowLayeredWindow = layoutElement.ShowLayeredWindow;
 }
        //=================================================================
        // Bound X/Y/Width/Height
        //=================================================================
        /// BoundX表示用
        /// @param layoutElement データ取得元のレイアウト要素
        /// @param isDummy ダミープレビューサイズかどうか
        /// @param sampleWidth サンプルの幅
        /// @param sampleHeight サンプルの高さ
        /// @param[out] x BoundXの文字列
        /// @param[out] y BoundYの文字列
        /// @param[out] width BoundWidthの文字列
        /// @param[out] height BoundHeightの文字列
        /// @return BoundX表示用文字列
        public static void GetBoundRectString(LayoutElement layoutElement,
            bool isDummy, int sampleWidth, int sampleHeight,
            out string x, out string y, out string width, out string height)
        {
            var boundRect = layoutElement.GetBoundRect(sampleWidth, sampleHeight);

            x = isDummy ? string.Format("({0})", boundRect.X)
                : boundRect.X.ToString();
            y = isDummy ? string.Format("({0})", boundRect.Y)
                : boundRect.Y.ToString();
            width = isDummy ? string.Format("({0})", boundRect.Width)
                    : boundRect.Width.ToString();
            height = isDummy ? string.Format("({0})", boundRect.Height)
                     : boundRect.Height.ToString();
        }
Пример #4
0
        //===================================================================
        // ヒットテスト
        //===================================================================
        /// ヒットテスト
        public static bool TryHitTest(Profile profile, RelativePoint mousePoint,
            out LayoutElement hitElement, out HitModes hitMode)
        {
            // 計算途中の結果をまとめるスタック
            var moveStack = new Stack<LayoutElement>();
            var sizeStack = new Stack<LayoutElement>();

            // レイアウト要素を線形探索
            foreach (var layoutElement in profile.LayoutElements) {
              // ヒットテスト対象外判定
              var maximumBoundRect = HitTest.GetMaximumBoundRect(layoutElement);
              if (!maximumBoundRect.Contains(mousePoint)) continue;

              var moveRect = HitTest.GetMoveRect(layoutElement);
              if (moveRect.Contains(mousePoint)) {
            // 移動用領域
            moveStack.Push(layoutElement);
              } else {
            // 移動用領域でない=サイズ変更用領域
            sizeStack.Push(layoutElement);
              }
            }

            // sizeStack優先
            foreach (var layoutElement in sizeStack) {
              // 見つかり次第終了
              hitMode = HitTest.GetHitMode(layoutElement, mousePoint);
              hitElement = layoutElement;
              return true;
            }

            // moveStack
            foreach (var layoutElement in moveStack) {
              // 見つかり次第終了
              hitMode = HitModes.Move;
              hitElement = layoutElement;
              return true;
            }

            hitElement = null;
            hitMode = HitModes.Neutral;
            return false;
        }
        /// レイアウト要素のヘッダーの生成
        /// @param layoutElement 対象のレイアウト要素
        /// @param index レイアウト要素のインデックス
        /// @param boundRect ヘッダー表示領域
        /// @param textBrush テキスト描画用ブラシ
        /// @return DrawingContext.DrawTextで描画可能なDrawingVisualオブジェクト
        private FormattedText CreateHeader(LayoutElement layoutElement,
            int index, Rect boundRect, Brush textBrush)
        {
            var isCurrent = layoutElement == App.Profile.Current;
            var isDummy = !App.RuntimeOptions.IsCurrentProcessIDValid;

            // Caption
            var header = StringConverter.GetHeaderStringForLayoutEdit(layoutElement,
            index, isCurrent, isDummy,
            App.RuntimeOptions.CurrentSampleWidth,
            App.RuntimeOptions.CurrentSampleHeight);

            // FormattedText
            var formattedText = new FormattedText(header,
            System.Globalization.CultureInfo.CurrentUICulture,
            FlowDirection.LeftToRight,
            new Typeface("Segoe UI, Tahoma"),
            CaptionFontSize,
            textBrush);

            // Clipping
            formattedText.MaxTextWidth = boundRect.Width;
            formattedText.MaxTextHeight = boundRect.Height;
            formattedText.MaxLineCount = 1;
            return formattedText;
        }
Пример #6
0
 //===================================================================
 // ヒットテスト用RelativeRectの生成
 //===================================================================
 /// レイアウト要素のうちボーダーを含めたRectを取得
 private static RelativeRect GetMaximumBoundRect(LayoutElement layoutElement)
 {
     return new RelativeRect(
     layoutElement.BoundRelativeLeft -
     Constants.BorderRelativeThickness,
     layoutElement.BoundRelativeTop -
     Constants.BorderRelativeThickness,
     layoutElement.BoundRelativeWidth +
     Constants.BorderRelativeThickness * 2,
     layoutElement.BoundRelativeHeight +
     Constants.BorderRelativeThickness * 2);
 }
Пример #7
0
 /// レイアウト要素のうちボーダーを含まないRectを取得
 private static RelativeRect GetMoveRect(LayoutElement layoutElement)
 {
     return new RelativeRect(
     layoutElement.BoundRelativeLeft +
     Constants.BorderRelativeThickness,
     layoutElement.BoundRelativeTop +
     Constants.BorderRelativeThickness,
     Math.Max(layoutElement.BoundRelativeWidth -
     Constants.BorderRelativeThickness * 2, 0.0),
     Math.Max(layoutElement.BoundRelativeHeight -
     Constants.BorderRelativeThickness * 2, 0.0));
 }
 //=================================================================
 // Header
 //=================================================================
 /// LayoutParameter用ヘッダー文字列
 /// @param layoutElement データ取得元のレイアウト要素
 /// @param index レイアウト要素のインデックス
 /// @param maxLength 文字列の長さの上限
 /// @return LayoutParameter用ヘッダー文字列
 public static string GetHeaderStringForLayoutParameter(LayoutElement layoutElement, int index, int maxLength)
 {
     var header = string.Format("Layout {0:D}: {1}",
                         index + 1,
                         layoutElement.WindowCaption);
     return header.Substring(0, Math.Min(header.Length, maxLength));
 }
 /// SWScaleChromaVShift表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleChromaVShift表示用文字列
 public static string GetSWScaleChromaVShiftString(LayoutElement layoutElement)
 {
     return layoutElement.SWScaleChromaVShift.ToString("F2");
 }
Пример #10
0
 /// SWScaleChromaGBlur表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleChromaGBlur表示用文字列
 public static string GetSWScaleChromaGBlurString(LayoutElement layoutElement)
 {
     return(layoutElement.SWScaleChromaGBlur.ToString("F2"));
 }
Пример #11
0
 /// SWScaleChromaVShift表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleChromaVShift表示用文字列
 public static string GetSWScaleChromaVShiftString(LayoutElement layoutElement)
 {
     return(layoutElement.SWScaleChromaVShift.ToString("F2"));
 }
Пример #12
0
        //===================================================================
        // 動作
        //===================================================================
        /// 開始
        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;
        }
Пример #13
0
 /// BoundRelativeRight表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return BoundRelativeRight表示用文字列
 public static string GetBoundRelativeRightString(LayoutElement layoutElement)
 {
     return(layoutElement.BoundRelativeRight.ToString("F3"));
 }
        /// DrawBorder用のスタイル(Brush,Pen)を生成
        private void CreateBorderStyle(LayoutElement layoutElement,
            out Pen framePen, out Brush textBrush)
        {
            var isCurrent = layoutElement == App.Profile.Current;

            // framePen/textBrush
            switch (layoutElement.WindowType) {
              case WindowTypes.Normal: {
            framePen  = isCurrent ? BrushesAndPens.CurrentNormalPen
                              : BrushesAndPens.NormalPen;
            textBrush = isCurrent ? BrushesAndPens.CurrentNormalBrush
                              : BrushesAndPens.NormalBrush;
            break;
              }
              case WindowTypes.DXGI: {
            framePen  = isCurrent ? BrushesAndPens.CurrentDXGIPen
                              : BrushesAndPens.DXGIPen;
            textBrush = isCurrent ? BrushesAndPens.CurrentDXGIBrush
                              : BrushesAndPens.DXGIBrush;
            break;
              }
              case WindowTypes.Desktop: {
            framePen  = isCurrent ? BrushesAndPens.CurrentDesktopPen
                              : BrushesAndPens.DesktopPen;
            textBrush = isCurrent ? BrushesAndPens.CurrentDesktopBrush
                              : BrushesAndPens.DesktopBrush;
            break;
              }
              default: Debug.Fail("switch"); throw new System.ArgumentException();
            }
        }
Пример #15
0
        //===================================================================
        // ヒットモード計算
        //===================================================================
        /// レイアウト要素とマウス座標(相対座標系)からHitModesを調べる
        /// @param layoutElement レイアウト要素
        /// @param mousePoint マウス座標(相対座標系)
        /// @return HitModes.SizeXXXのいずれか
        private static HitModes GetHitMode(LayoutElement layoutElement,
            RelativePoint mousePoint)
        {
            // ---------------
            // |  |1     |2  |
            // ---------------

            // H1
            var borderWRight = layoutElement.BoundRelativeLeft +
                       Constants.BorderRelativeThickness;
            // H2
            var borderELeft = layoutElement.BoundRelativeRight -
                      Constants.BorderRelativeThickness;

            // V1
            var borderNBottom = layoutElement.BoundRelativeTop +
                        Constants.BorderRelativeThickness;
            // v2
            var borderSTop = layoutElement.BoundRelativeBottom -
                     Constants.BorderRelativeThickness;

            // X座標→Y座標
            /// @attention 浮動小数点数の比較
            if (mousePoint.X < borderWRight) {          // W
              if (mousePoint.Y < borderNBottom) {       // N
            return HitModes.SizeNW;
              } else if (mousePoint.Y < borderSTop) {   // (N)-(S)
            return HitModes.SizeW;
              } else {                                  // S
            return HitModes.SizeSW;
              }
            } else if (mousePoint.X < borderELeft) {    // (W)-(E)
              if (mousePoint.Y < borderNBottom) {       // N
            return HitModes.SizeN;
              } else if (mousePoint.Y < borderSTop) {   // (N)-(S)
            Debug.Fail("Move?", "HitTest.GetHitMode");
            return HitModes.Move;
              } else {                                  // S
            return HitModes.SizeS;
              }
            } else {                                    // E
              if (mousePoint.Y < borderNBottom) {       // N
            return HitModes.SizeNE;
              } else if (mousePoint.Y < borderSTop) {   // (N)-(S)
            return HitModes.SizeE;
              } else {                                  // S
            return HitModes.SizeSE;
              }
            }
        }
 /// ClippingHeight表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return ClippingHeight表示用文字列
 public static string GetClippingHeightString(LayoutElement layoutElement)
 {
     if (layoutElement.Fit && !layoutElement.IsWindowValid) {
       return "n/a";
     } else if (layoutElement.Fit) {
       return string.Format("{0}*", layoutElement.ClippingHeightWithFit);
     } else {
       return layoutElement.ClippingHeightWithFit.ToString();
     }
 }
 /// BoundRelativeTop表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return BoundRelativeTop表示用文字列
 public static string GetBoundRelativeTopString(LayoutElement layoutElement)
 {
     return layoutElement.BoundRelativeTop.ToString("F3");
 }
 //=================================================================
 // SWScale
 //=================================================================
 /// SWScaleLumaGBlur表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleLumaGBlur表示用文字列
 public static string GetSWScaleLumaGBlurString(LayoutElement layoutElement)
 {
     return layoutElement.SWScaleLumaGBlur.ToString("F2");
 }
 //=================================================================
 // Window
 //=================================================================
 /// 表示用のウィンドウ名を取得
 public static string GetWindowCaption(LayoutElement layoutElement)
 {
     if (layoutElement.IsWindowValid) {
       return layoutElement.WindowCaption;
     } else {
       return string.Format("n/a ({0})", layoutElement.WindowCaption);
     }
 }
 /// SWScaleLumaSharpen表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleLumaSharpen表示用文字列
 public static string GetSWScaleLumaSharpenString(LayoutElement layoutElement)
 {
     return layoutElement.SWScaleLumaSharpen.ToString("F2");
 }
        /// 結果を取得
        /// @param layoutElement 対象のレイアウト要素
        /// @return 生成済みならBitmapSourceを。でなければNullを返す。
        public BitmapSource GetBitmapSource(LayoutElement layoutElement)
        {
            if (!layoutElement.IsWindowValid) return null;
            var request = new ScreenCaptureRequest(layoutElement);

            /// ディクショナリはスレッドセーフではない
            lock (this.sharedLock) {
              BitmapSource result;
              var success = this.cache.TryGetValue(request, out result);
              Debug.WriteLineIf(!success, "No request in cache", "ScreenCaptureTimer");
              return result;
            }
        }
        /// 枠線とキャプションの描画
        /// @param dc 描画先
        /// @param layoutElement 描画対象
        /// @param index 描画対象のインデックス
        private void DrawBorder(DrawingContext dc, LayoutElement layoutElement, int index)
        {
            // フレームサイズ
            var boundRect = layoutElement.GetBoundRect(
            App.RuntimeOptions.CurrentSampleWidth,
            App.RuntimeOptions.CurrentSampleHeight).ToRect();

            // スタイルの取得
            Brush textBrush;
            Pen framePen;
            this.CreateBorderStyle(layoutElement, out framePen, out textBrush);

            // フレームの描画
            var inflateValue = framePen.Thickness / 2;
            var infraleRect = Rect.Inflate(boundRect, -inflateValue, -inflateValue);
            dc.DrawRectangle(null, framePen, infraleRect);

            // ヘッダーのドロップシャドウの描画
            var shadowOffset = 1.0;
            var shadowPoint = new Point(boundRect.X + shadowOffset, boundRect.Y + shadowOffset);
            var shadowBoundRect = new Rect(boundRect.X + shadowOffset,
                                   boundRect.Y + shadowOffset,
                                   boundRect.Width - shadowOffset,
                                   boundRect.Height - shadowOffset);
            var shadow = this.CreateHeader(layoutElement, index, shadowBoundRect, BrushesAndPens.DropShadowBrush);
            dc.DrawText(shadow, shadowPoint);

            // ヘッダーの描画
            var headerPoint = new Point(boundRect.X, boundRect.Y);
            var header = this.CreateHeader(layoutElement, index, boundRect, textBrush);
            dc.DrawText(header, headerPoint);
        }
Пример #23
0
        /// フィールドを初期化
        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;
        }
 /// プレビュー画像の描画
 /// @param dc 描画先
 /// @param layoutElement 描画対象
 private void DrawPreview(DrawingContext dc, LayoutElement layoutElement)
 {
     var bitmap = App.ScreenCaptureTimer.GetBitmapSource(layoutElement);
     if (bitmap == null) {
       // エラーが起きた場合は赤色の四角形を描画
       var boundRect = layoutElement.GetBoundRect(
       App.RuntimeOptions.CurrentSampleWidth,
       App.RuntimeOptions.CurrentSampleHeight).ToRect();
       dc.DrawRectangle(Brushes.Red, null, boundRect);
     } else {
       // プレビューの描画
       var actualBoundRect = layoutElement.GetActualBoundRect(
       App.RuntimeOptions.CurrentSampleWidth,
       App.RuntimeOptions.CurrentSampleHeight).ToRect();
       dc.DrawImage(bitmap, actualBoundRect);
     }
 }
Пример #25
0
 /// BoundRelativeBottom表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return BoundRelativeBottom表示用文字列
 public static string GetBoundRelativeBottomString(LayoutElement layoutElement)
 {
     return(layoutElement.BoundRelativeBottom.ToString("F3"));
 }
Пример #26
0
 /// コンストラクタ
 public RelativeMouseOffset(LayoutElement layoutElement,
     RelativePoint mousePoint)
     : base(mousePoint.X - layoutElement.BoundRelativeLeft,
      mousePoint.Y - layoutElement.BoundRelativeTop,
      mousePoint.X - layoutElement.BoundRelativeRight,
      mousePoint.Y - layoutElement.BoundRelativeBottom)
 {
     // nop
 }
Пример #27
0
 /// SWScaleChromaSharpen表示用
 /// @param layoutElement データ取得元のレイアウト要素
 /// @return SWScaleChromaSharpen表示用文字列
 public static string GetSWScaleChromaSharpenString(LayoutElement layoutElement)
 {
     return(layoutElement.SWScaleChromaSharpen.ToString("F2"));
 }
 //-------------------------------------------------------------------
 /// レイアウト要素からClipping領域(Fitオプションなし)を取得
 private static ClientRect GetOriginal(LayoutElement layoutElement)
 {
     return new ClientRect(layoutElement.ClippingXWithoutFit,
                   layoutElement.ClippingYWithoutFit,
                   layoutElement.ClippingWidthWithoutFit,
                   layoutElement.ClippingHeightWithoutFit);
 }
Пример #29
0
 /// 全てのレイアウト要素を一気に更新する
 public void SetLayoutElements(List<LayoutElement> layoutElements, LayoutElement current)
 {
     this.LayoutElements = layoutElements;
     this.Current = current;
 }
 /// LayoutEdit用ヘッダー文字列
 /// @param layoutElement データ取得元のレイアウト要素
 /// @param index レイアウト要素のインデックス
 /// @param isCurrent 現在選択中のLayoutElementか
 /// @param isDummy ダミープレビューサイズかどうか
 /// @param sampleWidth サンプルの幅
 /// @param sampleHeight サンプルの高さ
 /// @return LayoutEdit用ヘッダー文字列
 public static string GetHeaderStringForLayoutEdit(
     LayoutElement layoutElement, int index,
     bool isCurrent, bool isDummy, int sampleWidth, int sampleHeight)
 {
     if (isCurrent && isDummy) {
       return string.Format(" [{0}] {1}", index + 1, layoutElement.WindowCaption);
     } else if (isCurrent) {
       var boundRect = layoutElement.GetBoundRect(sampleWidth, sampleHeight);
       return string.Format(" [{0}] ({1}x{2}) {3}",
       index + 1,
       boundRect.Width,
       boundRect.Height,
       layoutElement.WindowCaption);
     } else {
       return string.Format(" [{0}]", index + 1);
     }
 }