iPlug2 - C++ Audio Plug-in Framework
ReaperExtBase.cpp
1 ReaperExtBase::ReaperExtBase(reaper_plugin_info_t* pRec)
2 : EDITOR_DELEGATE_CLASS(0) // zero params
3 , mRec(pRec)
4 {
5  mTimer = std::unique_ptr<Timer>(Timer::Create(std::bind(&ReaperExtBase::OnTimer, this, std::placeholders::_1), IDLE_TIMER_RATE));
6 }
7 
8 ReaperExtBase::~ReaperExtBase()
9 {
10  mTimer->Stop();
11 };
12 
13 void ReaperExtBase::OnTimer(Timer& t)
14 {
15  OnIdle();
16 }
17 
18 auto ClientResize = [](HWND hWnd, int nWidth, int nHeight) {
19  RECT rcClient, rcWindow;
20  POINT ptDiff;
21  int screenwidth, screenheight;
22  int x, y;
23 
24  screenwidth = GetSystemMetrics(SM_CXSCREEN);
25  screenheight = GetSystemMetrics(SM_CYSCREEN);
26  x = (screenwidth / 2) - (nWidth / 2);
27  y = (screenheight / 2) - (nHeight / 2);
28 
29  GetClientRect(hWnd, &rcClient);
30  GetWindowRect(hWnd, &rcWindow);
31  ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
32  ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
33 
34  SetWindowPos(hWnd, 0, x, y, nWidth + ptDiff.x, nHeight + ptDiff.y, 0);
35 };
36 
37 bool ReaperExtBase::EditorResizeFromUI(int viewWidth, int viewHeight, bool needsPlatformResize)
38 {
39  if (viewWidth != GetEditorWidth() || viewHeight != GetEditorHeight())
40  {
41 #ifdef OS_MAC
42 #define TITLEBAR_BODGE 22 //TODO: sort this out
43  RECT r;
44  GetWindowRect(gHWND, &r);
45  SetWindowPos(gHWND, 0, r.left, r.bottom - viewHeight - TITLEBAR_BODGE, viewWidth, viewHeight + TITLEBAR_BODGE, 0);
46 #endif
47 
48  return true;
49  }
50 
51  return false;
52 }
53 
55 {
56  if(gHWND == NULL)
57  {
58  gHWND = CreateDialog(gHINSTANCE, MAKEINTRESOURCE(IDD_DIALOG_MAIN), gParent, ReaperExtBase::MainDlgProc);
59  }
60  else
61  DestroyWindow(gHWND);
62 }
63 
64 void ReaperExtBase::ToggleDocking()
65 {
66  if (!mDocked)
67  {
68  mDocked = true;
69  ShowWindow(gHWND, SW_HIDE);
70  DockWindowAdd(gHWND, (char*) "TEST", 0, false);
71  DockWindowActivate(gHWND);
72  }
73  else
74  {
75  DestroyWindow(gHWND);
76  mDocked = false;
77 // Show(false, true);
78  }
79 }
80 
81 void ReaperExtBase::RegisterAction(const char* actionName, std::function<void()> func, bool addMenuItem, int* pToggle/*, IKeyPress keyCmd*/)
82 {
83  ReaperAction action;
84 
85  int commandID = mRec->Register("command_id", (void*) actionName /* ?? */);
86 
87  assert(commandID);
88 
89  action.func = func;
90  action.accel.accel.cmd = commandID;
91  action.accel.desc = actionName;
92  action.addMenuItem = addMenuItem;
93  action.pToggle = pToggle;
94 
95  gActions.push_back(action);
96 
97  mRec->Register("gaccel", (void*) &gActions.back().accel);
98 }
99 
100 //static
101 bool ReaperExtBase::HookCommandProc(int command, int flag)
102 {
103  std::vector<ReaperAction>::iterator it = std::find_if (gActions.begin(), gActions.end(), [&](const auto& e) { return e.accel.accel.cmd == command; });
104 
105  if(it != gActions.end())
106  {
107  it->func();
108  }
109 
110  return false;
111 }
112 
113 //static
114 int ReaperExtBase::ToggleActionCallback(int command)
115 {
116  std::vector<ReaperAction>::iterator it = std::find_if (gActions.begin(), gActions.end(), [&](const auto& e) { return e.accel.accel.cmd == command; });
117 
118  if(it != gActions.end())
119  {
120  if(it->pToggle == nullptr)
121  return -1;
122  else
123  return *it->pToggle;
124  }
125 
126  return 0;
127 }
128 
129 //static
130 WDL_DLGRET ReaperExtBase::MainDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
131 {
132 // auto Resize = [&]()
133 // {
134 // RECT r;
135 // GetWindowRect(hwnd, &r);
136 // if(memcmp((void*) &r, (void*) &gPrevBounds, sizeof(RECT)) > 0)
137 // gPlug->GetUI()->Resize(r.right-r.left, r.bottom-r.top, 1);
138 //
139 // gPrevBounds = r;
140 // };
141 
142  extern float GetScaleForHWND(HWND hWnd);
143 
144  switch (uMsg)
145  {
146  case WM_INITDIALOG:
147  {
148  AttachWindowTopmostButton(hwnd);
149  gPlug->OpenWindow(hwnd);
150  auto scale = GetScaleForHWND(hwnd);
151  ClientResize(hwnd, PLUG_WIDTH * scale, PLUG_HEIGHT * scale);
152  ShowWindow(hwnd, SW_SHOW);
153  GetWindowRect(hwnd, &gPrevBounds);
154 
155  return 0;
156  }
157  case WM_DESTROY:
158  gHWND = NULL;
159  return 0;
160  case WM_CLOSE:
161  gPlug->CloseWindow();
162  DestroyWindow(hwnd);
163  return 0;
164 // case WM_SIZE:
165 // {
166  //Resize();
167 // return 0;
168 // }
169  }
170  return 0;
171 }
Base class for timer.
Definition: IPlugTimer.h:39
void RegisterAction(const char *actionName, std::function< void()> func, bool addMenuItem=false, int *pToggle=nullptr)
void ShowHideMainWindow()
Helper struct for registering Reaper Actions.