#include "ECTrainer.h"
#include "ECTrainerGUI.h"
#define CVUI_IMPLEMENTATION
#include "cvui.h"
#ifdef _DEBUG
#include <iostream>
#endif
// コンストラクタ
ECTrainerGUI::ECTrainerGUI(ECTrainer* pEct) :_pEct(pEct) {
}
// 初期化
bool ECTrainerGUI::Init() {
// 実行環境の情報取得
GetDisplayInfo();
// GUIウインドウ
cvui::init(WIN_MAIN);
_MainFrame.create(MAIN_FRAME_SIZE, CV_8UC3);
// 刺激提示ウインドウ
cv::namedWindow(WIN_DISP, cv::WINDOW_NORMAL | cv::WINDOW_OPENGL);
if (_Displays.size() > 1) {
// メインモニタの決定
int mainMonitor = 0, subMonitor = 1;
for (int i = 0; i < _Displays.size(); i++) {
if (_Displays[i].left == 0 && _Displays[i].top == 0) mainMonitor = i;
else subMonitor = i;
}
// マルチモニタの場合 サブ画面でフルスクリーン化
cv::moveWindow(WIN_DISP, _Displays[subMonitor].left, _Displays[subMonitor].top);
cv::setWindowProperty(WIN_DISP, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN);
_DispBuffer.create(cv::Size(_Displays[subMonitor].right - _Displays[subMonitor].left,
_Displays[subMonitor].bottom - _Displays[subMonitor].top), CV_8UC3);
cv::moveWindow(WIN_MAIN, _Displays[mainMonitor].left + 100, _Displays[mainMonitor].top + 100);
}
else {
// シングルモニタの場合
cv::moveWindow(WIN_DISP, _Displays[0].left, _Displays[0].top);
_DispBuffer.create(cv::Size(640, 480), CV_8UC3);
cv::moveWindow(WIN_MAIN, _Displays[0].left + 100, _Displays[0].top + 100);
}
cv::Mat opening = cv::imread("../images/ECTrainerLogo640x91.png");
SetDispBuffer(opening);
_SceneBuffer.create(SCENE_BUFFER_SIZE, CV_8UC3);
_SceneBuffer = CV_RGB(0, 0, 0);
_Logo = cv::imread("../images/ECTrainerLogo640x91.png");
//_DispBuffer = cv::imread("../images/calib.png");
return true;
}
// イベントループ
bool ECTrainerGUI::MainLoop() {
while (_pEct->IsRunning() && cv::getWindowProperty(WIN_MAIN, 0) >= 0) {
// メインウインドウフレーム生成
_MainFrame = cv::Scalar(49, 52, 49);
cvui::image(_MainFrame, 0, 0, _Logo);
cvui::beginRow(_MainFrame, 10, 100, -1, -1, 10);
cvui::beginColumn(-1, -1, 10);
if (cvui::button("Calibration")) _pEct->Calib();
if (cvui::button("Start")) _pEct->Start();
if (cvui::button("Quit")) _pEct->Stop();
cvui::endColumn();
cvui::beginColumn();
cvui::text("View camera");
cvui::space();
cvui::image(_SceneBuffer);
cvui::endColumn();
cvui::endRow();
// 画面表示
cvui::update();
cv::imshow(WIN_MAIN, _MainFrame);
cv::imshow(WIN_DISP, _DispBuffer);
int key = cv::waitKey(1);
if (key == KEY_ESC) _pEct->Stop();
}
return true;
}
// 視野画像バッファに画像を設定
void ECTrainerGUI::SetSceneBuffer(cv::Mat& img) {
cv::resize(img, _SceneBuffer, SCENE_BUFFER_SIZE);
}
// 刺激画像バッファに画像を設定
void ECTrainerGUI::SetDispBuffer(cv::Mat& img) {
_DispBuffer = cv::Scalar(0, 0, 0);
cv::Rect roiRect;
if (img.rows * _DispBuffer.cols / _DispBuffer.rows > img.cols) {
roiRect.width = img.cols * _DispBuffer.rows / img.rows;
roiRect.height = _DispBuffer.rows;
} else {
roiRect.width = _DispBuffer.cols;
roiRect.height = img.rows * _DispBuffer.cols / img.cols;
}
roiRect.x = (_DispBuffer.cols - roiRect.width) / 2;
roiRect.y = (_DispBuffer.rows - roiRect.height) / 2;
if (roiRect.x + roiRect.width > _DispBuffer.cols) roiRect.width = _DispBuffer.cols - roiRect.x;
if (roiRect.y + roiRect.height > _DispBuffer.rows) roiRect.height = _DispBuffer.rows - roiRect.y;
cv::Mat roi(_DispBuffer, roiRect);
cv::resize(img, roi, roi.size());
}
// 全ディスプレイの情報を取得
void ECTrainerGUI::GetDisplayInfo() {
EnumDisplayMonitors(NULL, NULL,
(MONITORENUMPROC)MonitorEnumProc, (LPARAM)&_Displays);
#ifdef _DEBUG
for (int i = 0; i < _Displays.size(); i++) {
std::cout << "Monitor" << i << " : "
<< _Displays[i].left << "," << _Displays[i].top << ","
<< _Displays[i].right << "," << _Displays[i].bottom << std::endl;
}
#endif // _DEBUG
}
// 各ディスプレイの情報を取得
BOOL CALLBACK ECTrainerGUI::MonitorEnumProc(
HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwData) {
std::vector<RECT>* displays = (std::vector<RECT>*)dwData;
displays->push_back(*lpMon);
return TRUE;
}