ToolState.h
  1  #pragma once
  2  
  3  #include <array>
  4  #include <functional>
  5  #include <mutex>
  6  #include <vector>
  7  #include <thread>
  8  #include <unordered_map>
  9  
 10  #include <windef.h>
 11  #include <d2d1helper.h>
 12  #include <dCommon.h>
 13  
 14  #include <common/Display/monitors.h>
 15  #include <common/utils/serialized.h>
 16  
 17  //#define DEBUG_OVERLAY
 18  #include "BGRATextureView.h"
 19  #include "Measurement.h"
 20  
 21  struct OverlayBoxText
 22  {
 23      std::array<wchar_t, 128> buffer = {};
 24  };
 25  
 26  struct CommonState
 27  {
 28      std::function<void()> sessionCompletedCallback;
 29      D2D1::ColorF lineColor = D2D1::ColorF::OrangeRed;
 30      Box toolbarBoundingBox;
 31  
 32      Measurement::Unit units = Measurement::Unit::Pixel;
 33  
 34      #pragma warning(push)
 35      #pragma warning(disable : 4324)
 36      alignas(8) POINT cursorPosSystemSpace = {}; // updated atomically
 37      #pragma warning(pop)
 38  
 39      std::atomic_bool closeOnOtherMonitors = false;
 40  
 41      float GetPhysicalPx2MmRatio(HWND window) const
 42      {
 43          auto ratio = -1.0f;
 44          auto size = MonitorInfo::GetFromWindow(window).GetSize();
 45          if (size.width_physical > 0u)
 46          {
 47              ratio = size.width_mm / static_cast<float>(size.width_physical);
 48          }
 49          return ratio;
 50      }
 51  };
 52  
 53  struct CursorDrag
 54  {
 55      D2D_POINT_2F startPos = {};
 56      D2D_POINT_2F currentPos = {};
 57      DWORD touchID = 0; // indicate whether the drag belongs to a touch input sequence
 58  };
 59  
 60  struct BoundsToolState
 61  {
 62      struct PerScreen
 63      {
 64          std::optional<CursorDrag> currentBounds;
 65          std::vector<Measurement> measurements;
 66      };
 67  
 68      // TODO: refactor so we don't need unordered_map
 69      std::unordered_map<HWND, PerScreen> perScreen;
 70  
 71      CommonState* commonState = nullptr; // required for WndProc
 72  };
 73  
 74  struct MeasureToolState
 75  {
 76      enum class Mode
 77      {
 78          Horizontal,
 79          Vertical,
 80          Cross
 81      };
 82  
 83      struct Global
 84      {
 85          uint8_t pixelTolerance = 30;
 86          bool continuousCapture = false;
 87          bool drawFeetOnCross = true;
 88          bool perColorChannelEdgeDetection = false;
 89          Mode mode = Mode::Cross;
 90      } global;
 91  
 92      struct PerScreen
 93      {
 94          using PrevMeasurement = std::pair<POINT, Measurement>;
 95  
 96          bool cursorInLeftScreenHalf = false;
 97          bool cursorInTopScreenHalf = false;
 98          std::optional<Measurement> measuredEdges;
 99          std::vector<PrevMeasurement> prevMeasurements;
100  
101          // While not in a continuous capturing mode, we need to draw captured backgrounds. These are passed
102          // directly from a capturing thread.
103          const MappedTextureView* capturedScreenTexture = nullptr;
104          // After the drawing thread finds its capturedScreenTexture, it converts it to
105          // a Direct2D compatible bitmap and caches it here
106          winrt::com_ptr<ID2D1Bitmap> capturedScreenBitmap;
107      };
108      std::unordered_map<HWND, PerScreen> perScreen;
109  
110      CommonState* commonState = nullptr; // required for WndProc
111  };