//===================================================================
        // コンストラクタ
        //===================================================================
        /// コンストラクタ
        public SnapGuide(Profile profile)
        {
            foreach (var layoutElement in profile.LayoutElements) {
              // currentにSnapさせる必要はない
              if (layoutElement == profile.Current) continue;

              // Top/Leftは先に、Right/Bottomは後に
              verticalSnapGuides.AddFirst(layoutElement.BoundRelativeTop);
              verticalSnapGuides.AddLast(layoutElement.BoundRelativeBottom);
              horizontalSnapGuides.AddFirst(layoutElement.BoundRelativeLeft);
              horizontalSnapGuides.AddLast(layoutElement.BoundRelativeRight);
            }
        }
示例#2
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 profile プロファイル
        /// @attention UIスレッド上で実行されることを想定している
        public void UpdateRequest(Profile profile)
        {
            // ProfileからRequestを生成
            var profileRequests = new HashSet<ScreenCaptureRequest>();
            foreach (var layoutElement in profile.LayoutElements) {
              if (!layoutElement.IsWindowValid) continue;
              profileRequests.Add(new ScreenCaptureRequest(layoutElement));
            }

            lock (this.sharedLock) {
              Debug.Assert(this.isRunning, "Must be running", "ScreenCaptureTimer");

              // 三つの場合で処理がわかれる
              // 1. profileにもcacheにも含まれている = nop
              // 2. cacheにはあるがprofileにはない = メモリ解放
              // 3. profileにはあるがcacheにはない = cacheに追加して即時更新
              var onlycacheRequests = new HashSet<ScreenCaptureRequest>(this.cache.Keys);
              onlycacheRequests.ExceptWith(profileRequests);
              var onlyProfileRequests = profileRequests; // もう使わないのでCloneしない
              onlyProfileRequests.ExceptWith(this.cache.Keys);

              // 2.
              var needGC = false;
              foreach (var request in onlycacheRequests) {
            this.cache[request] = null;
            var result = this.cache.Remove(request);
            Debug.WriteLineIf(!result, "!");
            needGC = true;
              }
              if (needGC) {
            Debug.Write("G");
            GC.Collect();
            //GC.WaitForPendingFinalizers();
            //GC.Collect();
              }

              // 3.
              foreach (var request in onlyProfileRequests) {
            // var bitmapSource = this.Capture(request);
            var bitmapSource = this.CaptureByGetDIBits(request);
            Debug.WriteIf(bitmapSource != null, "x");
            this.cache[request] = bitmapSource;
              }
            }
        }