|
|
@@ -18,6 +18,17 @@
|
|
|
using boost::asio::ip::tcp;
|
|
|
|
|
|
#include "../tool/CFoodHandle.h"
|
|
|
+#include "../tool/CAppEnv.h"
|
|
|
+#include "../tool/CVideoCapture.h"
|
|
|
+
|
|
|
+namespace
|
|
|
+{
|
|
|
+ const int kVideoPreviewWidth = 600;
|
|
|
+ const int kVideoPreviewHeight = 450;
|
|
|
+ const int kVideoMinWidth = 400;
|
|
|
+ const int kVideoMinHeight = 300;
|
|
|
+ const int kVideoGripSize = 8;
|
|
|
+}
|
|
|
|
|
|
CSettingPageUI::CSettingPageUI()
|
|
|
{
|
|
|
@@ -27,6 +38,19 @@ CSettingPageUI::CSettingPageUI()
|
|
|
|
|
|
CSettingPageUI::~CSettingPageUI()
|
|
|
{
|
|
|
+ m_is_show_video_capture = false;
|
|
|
+
|
|
|
+ if (m_hBitmap)
|
|
|
+ {
|
|
|
+ DeleteObject(m_hBitmap);
|
|
|
+ m_hBitmap = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_hMemDC)
|
|
|
+ {
|
|
|
+ DeleteDC(m_hMemDC);
|
|
|
+ m_hMemDC = NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//初始化当前页面的展示,处理默认展示效果,在页面被加载的时候调用
|
|
|
@@ -1698,80 +1722,18 @@ void CSettingPageUI::HandleSelectChangeMsg(TNotifyUI& msg)
|
|
|
{
|
|
|
CDuiString name = msg.pSender->GetName();
|
|
|
|
|
|
- //判断设置中心的tab
|
|
|
- if (name == _T("setting_waimai_order_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(0);
|
|
|
- }
|
|
|
- if (name == _T("setting_diannei_order_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(1);
|
|
|
- }
|
|
|
- else if (name == _T("setting_printer_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(2);
|
|
|
- }
|
|
|
- else if (name == _T("setting_biaoqian_printer_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(3);
|
|
|
- }
|
|
|
- else if (name == _T("setting_chufang_printer_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(4);
|
|
|
- }
|
|
|
- else if (name == _T("setting_dianzicheng_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(5);
|
|
|
- }
|
|
|
- else if (name == _T("setting_tiaomacheng_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(6);
|
|
|
- }
|
|
|
- else if (name == _T("setting_ai_recognition_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI * pControl = static_cast<CTabLayoutUI *>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(7);
|
|
|
- }
|
|
|
- else if (name == _T("setting_xianshi_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(8);
|
|
|
- }
|
|
|
- else if (name == _T("setting_tongbu_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(9);
|
|
|
+ std::wstring ws_name = name.GetData();
|
|
|
|
|
|
- CLabelUI* label = static_cast<CLabelUI*>(this->FindSubControl(L"setting_tongbu_result"));
|
|
|
- label->SetVisible(false);
|
|
|
- }
|
|
|
- else if (name == _T("setting_kuaijiejian_switch"))
|
|
|
+ if (ws_name.find(L"setting_switch_page_") == 0)
|
|
|
{
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(10);
|
|
|
+ //说明是点击了切换设置页面
|
|
|
+ this->SwitchSettingPage(ws_name);
|
|
|
|
|
|
- CButtonUI* focusEdit = static_cast<CButtonUI*>(this->FindSubControl(_T("setting_kuaijiejian_page_btn_weixinshoukuan")));
|
|
|
-
|
|
|
- m_pManager->SetFocus(NULL);
|
|
|
- }
|
|
|
- else if (name == _T("setting_system_switch"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(11);
|
|
|
- }
|
|
|
- else if (name == _T("setting_system_about"))
|
|
|
- {
|
|
|
- CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
- pControl->SelectItem(12);
|
|
|
+ return;
|
|
|
}
|
|
|
- else if (name == _T("xianshi_setting_youtu"))
|
|
|
+
|
|
|
+ //判断设置中心非页面切换的tab
|
|
|
+ if (name == _T("xianshi_setting_youtu"))
|
|
|
{
|
|
|
CSetting::GetInstance()->SetParam("setting_xianshi_is_youtu", "1");
|
|
|
}
|
|
|
@@ -2113,6 +2075,8 @@ bool CSettingPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam
|
|
|
|
|
|
label->SetText(L"同步成功!");
|
|
|
label->SetVisible(true);
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
else if (uMsg == WM_SETTING_TONGBU_FAIL)
|
|
|
{
|
|
|
@@ -2120,6 +2084,8 @@ bool CSettingPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam
|
|
|
|
|
|
label->SetText(m_tongbu_error.c_str());
|
|
|
label->SetVisible(true);
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
else if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP)
|
|
|
{
|
|
|
@@ -2130,6 +2096,18 @@ bool CSettingPageUI::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam
|
|
|
return OnHotKeyDown(uMsg, wParam, lParam);
|
|
|
}
|
|
|
}
|
|
|
+ else if (uMsg == WM_SETCURSOR || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
|
|
|
+ {
|
|
|
+ if (HandleVideoBorderMouseMessage(uMsg, wParam, lParam))
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (uMsg == WM_AI_XUEXI_UPDATE)
|
|
|
+ {
|
|
|
+ UpdateVideoShow();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
@@ -3380,4 +3358,524 @@ void CSettingPageUI::InitKuaijiejianShow()
|
|
|
|
|
|
CButtonUI* shoukuan_edit = static_cast<CButtonUI*>(this->FindSubControl(_T("setting_kuaijiejian_page_btn_tiaozhuan_shoukuan")));
|
|
|
shoukuan_edit->SetText(shoukuan_info);
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::SwitchSettingPage(std::wstring page_name)
|
|
|
+{
|
|
|
+ if (page_name == _T("setting_switch_page_waimai_order"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(0);
|
|
|
+ }
|
|
|
+ if (page_name == _T("setting_switch_page_diannei_order"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(1);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_printer"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(2);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_biaoqian_printer"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(3);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_chufang_printer"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(4);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_dianzicheng"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(5);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_tiaomacheng"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(6);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_ai_recognition"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(7);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_xianshi"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(8);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_tongbu"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(9);
|
|
|
+
|
|
|
+ CLabelUI* label = static_cast<CLabelUI*>(this->FindSubControl(L"setting_tongbu_result"));
|
|
|
+ label->SetVisible(false);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_kuaijiejian"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(10);
|
|
|
+
|
|
|
+ CButtonUI* focusEdit = static_cast<CButtonUI*>(this->FindSubControl(_T("setting_kuaijiejian_page_btn_weixinshoukuan")));
|
|
|
+
|
|
|
+ m_pManager->SetFocus(NULL);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_system"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(11);
|
|
|
+ }
|
|
|
+ else if (page_name == _T("setting_switch_page_system_about"))
|
|
|
+ {
|
|
|
+ CTabLayoutUI* pControl = static_cast<CTabLayoutUI*>(this->FindSubControl(_T("setting_switch")));
|
|
|
+ pControl->SelectItem(12);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (page_name == _T("setting_switch_page_ai_recognition"))
|
|
|
+ {
|
|
|
+ if (m_is_show_video_capture == false)
|
|
|
+ {
|
|
|
+ //需要启动摄像头进程
|
|
|
+ std::thread(&CSettingPageUI::HandleUpdateVideo, this).detach();
|
|
|
+ CAppEnv::GetInstance()->AddWorkerNum();
|
|
|
+ }
|
|
|
+
|
|
|
+ m_is_show_video_capture = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ m_is_show_video_capture = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::HandleUpdateVideo()
|
|
|
+{
|
|
|
+ while (m_is_show_video_capture == true)
|
|
|
+ {
|
|
|
+ if (m_pMainWnd->GetCurPageName() != CMainWnd::SETTING)
|
|
|
+ {
|
|
|
+ //如果不是在设置页面,这个线程直接结束
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ cv::Mat img;
|
|
|
+ CVideoCapture::GetInstance()->GetFrame(img);
|
|
|
+ if (img.empty())
|
|
|
+{
|
|
|
+ //摄像头有问题,等待一会再重新读取
|
|
|
+ Sleep(1000);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (img.type() != CV_8UC3)
|
|
|
+ {
|
|
|
+ // 仅支持 3 通道彩色图像
|
|
|
+ cvtColor(img, img, cv::COLOR_GRAY2BGR);
|
|
|
+ }
|
|
|
+
|
|
|
+ //缩放尺寸,适合在界面上展示,过大过小都不好看,这个尺寸是根据界面上image控件的大小来定的,可以根据实际情况调整
|
|
|
+ cv::resize(img, img, cv::Size(kVideoPreviewWidth, kVideoPreviewHeight), 0, 0, cv::INTER_LINEAR);
|
|
|
+
|
|
|
+ // 创建或更新位图
|
|
|
+ HDC hDC = GetDC(NULL);
|
|
|
+ if (m_hBitmap)
|
|
|
+ {
|
|
|
+ DeleteObject(m_hBitmap);
|
|
|
+ }
|
|
|
+
|
|
|
+ BITMAPINFO bmi = { 0 };
|
|
|
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
+ bmi.bmiHeader.biWidth = img.cols;
|
|
|
+ bmi.bmiHeader.biHeight = -img.rows; // 翻转 Y 轴(OpenCV 与 GDI 坐标方向相反)
|
|
|
+ bmi.bmiHeader.biPlanes = 1;
|
|
|
+ bmi.bmiHeader.biBitCount = 24;
|
|
|
+ bmi.bmiHeader.biCompression = BI_RGB;
|
|
|
+
|
|
|
+ m_hBitmap = CreateDIBitmap(hDC, &bmi.bmiHeader, CBM_INIT, img.data, &bmi, DIB_RGB_COLORS);
|
|
|
+ ReleaseDC(NULL, hDC);
|
|
|
+
|
|
|
+ //位图已经生成好,发送消息进行刷新显示
|
|
|
+ ::PostMessage(m_pMainWnd->GetHWND(), WM_AI_XUEXI_UPDATE, 0, 0);
|
|
|
+
|
|
|
+ // 控制帧率,避免过度占用 CPU,30 FPS 大约是每 33 毫秒更新一次
|
|
|
+ Sleep(1000 / 30);
|
|
|
+ }
|
|
|
+
|
|
|
+ CAppEnv::GetInstance()->DelWorkerNum();
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::UpdateVideoShow()
|
|
|
+{
|
|
|
+ LoadVideoBorderRect();
|
|
|
+
|
|
|
+ HDC hDC = m_pManager->GetPaintDC();
|
|
|
+ if (!hDC || !m_hBitmap)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!m_hMemDC)
|
|
|
+ {
|
|
|
+ m_hMemDC = CreateCompatibleDC(hDC);
|
|
|
+ }
|
|
|
+
|
|
|
+ CControlUI* pImage = static_cast<CControlUI*>(this->FindSubControl(_T("image_video")));
|
|
|
+ if (!pImage)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ BITMAP bm = { 0 };
|
|
|
+ GetObject(m_hBitmap, sizeof(BITMAP), &bm);
|
|
|
+ if (bm.bmWidth <= 0 || bm.bmHeight <= 0)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
|
|
|
+
|
|
|
+ RECT imageRect = pImage->GetPos();
|
|
|
+ int imageWidth = imageRect.right - imageRect.left;
|
|
|
+ int imageHeight = imageRect.bottom - imageRect.top;
|
|
|
+ if (imageWidth <= 0 || imageHeight <= 0)
|
|
|
+ {
|
|
|
+ SelectObject(m_hMemDC, hOldBitmap);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ StretchBlt(hDC, imageRect.left, imageRect.top, imageRect.right - imageRect.left,
|
|
|
+ imageRect.bottom - imageRect.top, m_hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
|
|
|
+
|
|
|
+ RECT borderRect = GetVideoBorderDisplayRect(imageRect);
|
|
|
+
|
|
|
+ int savedDc = SaveDC(hDC);
|
|
|
+ IntersectClipRect(hDC, imageRect.left, imageRect.top, imageRect.right, imageRect.bottom);
|
|
|
+
|
|
|
+ HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
|
|
|
+ HPEN hOldPen = (HPEN)SelectObject(hDC, hPen);
|
|
|
+ HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, GetStockObject(NULL_BRUSH));
|
|
|
+
|
|
|
+ Rectangle(hDC, borderRect.left, borderRect.top, borderRect.right, borderRect.bottom);
|
|
|
+
|
|
|
+ HBRUSH hHandleBrush = CreateSolidBrush(RGB(255, 0, 0));
|
|
|
+ auto drawHandle = [&](int x, int y)
|
|
|
+ {
|
|
|
+ const int half = 4;
|
|
|
+ RECT rc = { x - half, y - half, x + half, y + half };
|
|
|
+ FillRect(hDC, &rc, hHandleBrush);
|
|
|
+ };
|
|
|
+
|
|
|
+ int cx = (borderRect.left + borderRect.right) / 2;
|
|
|
+ int cy = (borderRect.top + borderRect.bottom) / 2;
|
|
|
+
|
|
|
+ /*
|
|
|
+ drawHandle(borderRect.left, borderRect.top);
|
|
|
+ drawHandle(borderRect.right, borderRect.top);
|
|
|
+ drawHandle(borderRect.left, borderRect.bottom);
|
|
|
+ drawHandle(borderRect.right, borderRect.bottom);
|
|
|
+
|
|
|
+ drawHandle(cx, borderRect.top);
|
|
|
+ drawHandle(cx, borderRect.bottom);
|
|
|
+ drawHandle(borderRect.left, cy);
|
|
|
+ drawHandle(borderRect.right, cy);
|
|
|
+ */
|
|
|
+
|
|
|
+ drawHandle(borderRect.left + 4, borderRect.top + 4);
|
|
|
+ drawHandle(borderRect.right - 4, borderRect.top + 4);
|
|
|
+ drawHandle(borderRect.left + 4, borderRect.bottom - 4);
|
|
|
+ drawHandle(borderRect.right - 4, borderRect.bottom - 4);
|
|
|
+
|
|
|
+ drawHandle(cx, borderRect.top + 4);
|
|
|
+ drawHandle(cx, borderRect.bottom - 4);
|
|
|
+ drawHandle(borderRect.left + 4, cy);
|
|
|
+ drawHandle(borderRect.right - 4, cy);
|
|
|
+
|
|
|
+ DeleteObject(hHandleBrush);
|
|
|
+ SelectObject(hDC, hOldBrush);
|
|
|
+ SelectObject(hDC, hOldPen);
|
|
|
+ DeleteObject(hPen);
|
|
|
+
|
|
|
+ RestoreDC(hDC, savedDc);
|
|
|
+
|
|
|
+ SelectObject(m_hMemDC, hOldBitmap);
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::StopVideoThread()
|
|
|
+{
|
|
|
+ m_is_show_video_capture = false;
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::LoadVideoBorderRect()
|
|
|
+{
|
|
|
+ if (m_videoBorderLoaded)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto readInt = [](const std::string& value, int defaultValue) -> int
|
|
|
+ {
|
|
|
+ if (value.empty())
|
|
|
+ {
|
|
|
+ return defaultValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ return atoi(value.c_str());
|
|
|
+ };
|
|
|
+
|
|
|
+ int x = readInt(CSetting::GetInstance()->GetParam("setting_ai_video_rect_x"), 0);
|
|
|
+ int y = readInt(CSetting::GetInstance()->GetParam("setting_ai_video_rect_y"), 0);
|
|
|
+ int w = readInt(CSetting::GetInstance()->GetParam("setting_ai_video_rect_w"), kVideoPreviewWidth);
|
|
|
+ int h = readInt(CSetting::GetInstance()->GetParam("setting_ai_video_rect_h"), kVideoPreviewHeight);
|
|
|
+
|
|
|
+ if (w < kVideoMinWidth) w = kVideoMinWidth;
|
|
|
+ if (h < kVideoMinHeight) h = kVideoMinHeight;
|
|
|
+ if (w > kVideoPreviewWidth) w = kVideoPreviewWidth;
|
|
|
+ if (h > kVideoPreviewHeight) h = kVideoPreviewHeight;
|
|
|
+
|
|
|
+ if (x < 0) x = 0;
|
|
|
+ if (y < 0) y = 0;
|
|
|
+ if (x + w > kVideoPreviewWidth) x = kVideoPreviewWidth - w;
|
|
|
+ if (y + h > kVideoPreviewHeight) y = kVideoPreviewHeight - h;
|
|
|
+
|
|
|
+ m_videoBorderRect.left = x;
|
|
|
+ m_videoBorderRect.top = y;
|
|
|
+ m_videoBorderRect.right = x + w;
|
|
|
+ m_videoBorderRect.bottom = y + h;
|
|
|
+
|
|
|
+ m_videoBorderLoaded = true;
|
|
|
+}
|
|
|
+
|
|
|
+void CSettingPageUI::SaveVideoBorderRect()
|
|
|
+{
|
|
|
+ int x = m_videoBorderRect.left;
|
|
|
+ int y = m_videoBorderRect.top;
|
|
|
+ int w = m_videoBorderRect.right - m_videoBorderRect.left;
|
|
|
+ int h = m_videoBorderRect.bottom - m_videoBorderRect.top;
|
|
|
+
|
|
|
+ CSetting::GetInstance()->SetParam("setting_ai_video_rect_x", std::to_string(x));
|
|
|
+ CSetting::GetInstance()->SetParam("setting_ai_video_rect_y", std::to_string(y));
|
|
|
+ CSetting::GetInstance()->SetParam("setting_ai_video_rect_w", std::to_string(w));
|
|
|
+ CSetting::GetInstance()->SetParam("setting_ai_video_rect_h", std::to_string(h));
|
|
|
+}
|
|
|
+
|
|
|
+RECT CSettingPageUI::GetVideoImageRect()
|
|
|
+{
|
|
|
+ RECT rc = { 0, 0, 0, 0 };
|
|
|
+
|
|
|
+ CControlUI* pImage = static_cast<CControlUI*>(this->FindSubControl(_T("image_video")));
|
|
|
+ if (!pImage)
|
|
|
+ {
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return pImage->GetPos();
|
|
|
+}
|
|
|
+
|
|
|
+RECT CSettingPageUI::GetVideoBorderDisplayRect(const RECT& imageRect)
|
|
|
+{
|
|
|
+ RECT rc = { 0, 0, 0, 0 };
|
|
|
+
|
|
|
+ int imageWidth = imageRect.right - imageRect.left;
|
|
|
+ int imageHeight = imageRect.bottom - imageRect.top;
|
|
|
+ if (imageWidth <= 0 || imageHeight <= 0)
|
|
|
+ {
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc.left = imageRect.left + MulDiv(m_videoBorderRect.left, imageWidth, kVideoPreviewWidth);
|
|
|
+ rc.top = imageRect.top + MulDiv(m_videoBorderRect.top, imageHeight, kVideoPreviewHeight);
|
|
|
+ rc.right = imageRect.left + MulDiv(m_videoBorderRect.right, imageWidth, kVideoPreviewWidth);
|
|
|
+ rc.bottom = imageRect.top + MulDiv(m_videoBorderRect.bottom, imageHeight, kVideoPreviewHeight);
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+int CSettingPageUI::HitTestVideoBorder(POINT pt, const RECT& borderRect)
|
|
|
+{
|
|
|
+ bool nearLeft = (std::abs(pt.x - borderRect.left) <= kVideoGripSize) &&
|
|
|
+ (pt.y >= borderRect.top - kVideoGripSize) &&
|
|
|
+ (pt.y <= borderRect.bottom + kVideoGripSize);
|
|
|
+
|
|
|
+ bool nearRight = (std::abs(pt.x - borderRect.right) <= kVideoGripSize) &&
|
|
|
+ (pt.y >= borderRect.top - kVideoGripSize) &&
|
|
|
+ (pt.y <= borderRect.bottom + kVideoGripSize);
|
|
|
+
|
|
|
+ bool nearTop = (std::abs(pt.y - borderRect.top) <= kVideoGripSize) &&
|
|
|
+ (pt.x >= borderRect.left - kVideoGripSize) &&
|
|
|
+ (pt.x <= borderRect.right + kVideoGripSize);
|
|
|
+
|
|
|
+ bool nearBottom = (std::abs(pt.y - borderRect.bottom) <= kVideoGripSize) &&
|
|
|
+ (pt.x >= borderRect.left - kVideoGripSize) &&
|
|
|
+ (pt.x <= borderRect.right + kVideoGripSize);
|
|
|
+
|
|
|
+ if (nearLeft && nearTop) return HTTOPLEFT;
|
|
|
+ if (nearRight && nearTop) return HTTOPRIGHT;
|
|
|
+ if (nearLeft && nearBottom) return HTBOTTOMLEFT;
|
|
|
+ if (nearRight && nearBottom) return HTBOTTOMRIGHT;
|
|
|
+
|
|
|
+ if (nearLeft && pt.y >= borderRect.top && pt.y <= borderRect.bottom) return HTLEFT;
|
|
|
+ if (nearRight && pt.y >= borderRect.top && pt.y <= borderRect.bottom) return HTRIGHT;
|
|
|
+ if (nearTop && pt.x >= borderRect.left && pt.x <= borderRect.right) return HTTOP;
|
|
|
+ if (nearBottom && pt.x >= borderRect.left && pt.x <= borderRect.right) return HTBOTTOM;
|
|
|
+
|
|
|
+ return HTNOWHERE;
|
|
|
+}
|
|
|
+
|
|
|
+bool CSettingPageUI::HandleVideoBorderMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
+{
|
|
|
+ if (!m_is_show_video_capture)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ LoadVideoBorderRect();
|
|
|
+
|
|
|
+ RECT imageRect = GetVideoImageRect();
|
|
|
+ int imageWidth = imageRect.right - imageRect.left;
|
|
|
+ int imageHeight = imageRect.bottom - imageRect.top;
|
|
|
+ if (imageWidth <= 0 || imageHeight <= 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ RECT borderRect = GetVideoBorderDisplayRect(imageRect);
|
|
|
+
|
|
|
+ auto setCursorByHit = [](int hitType) -> bool
|
|
|
+ {
|
|
|
+ LPCTSTR cursorId = IDC_ARROW;
|
|
|
+
|
|
|
+ switch (hitType)
|
|
|
+ {
|
|
|
+ case HTLEFT:
|
|
|
+ case HTRIGHT:
|
|
|
+ cursorId = IDC_SIZEWE;
|
|
|
+ break;
|
|
|
+ case HTTOP:
|
|
|
+ case HTBOTTOM:
|
|
|
+ cursorId = IDC_SIZENS;
|
|
|
+ break;
|
|
|
+ case HTTOPLEFT:
|
|
|
+ case HTBOTTOMRIGHT:
|
|
|
+ cursorId = IDC_SIZENWSE;
|
|
|
+ break;
|
|
|
+ case HTTOPRIGHT:
|
|
|
+ case HTBOTTOMLEFT:
|
|
|
+ cursorId = IDC_SIZENESW;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::SetCursor(::LoadCursor(NULL, cursorId));
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+
|
|
|
+ if (uMsg == WM_SETCURSOR)
|
|
|
+ {
|
|
|
+ if (LOWORD(lParam) != HTCLIENT)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ POINT pt;
|
|
|
+ ::GetCursorPos(&pt);
|
|
|
+ ::ScreenToClient(m_pMainWnd->GetHWND(), &pt);
|
|
|
+
|
|
|
+ int hitType = m_isDraggingVideoBorder ? m_videoBorderHitType : HitTestVideoBorder(pt, borderRect);
|
|
|
+ return setCursorByHit(hitType);
|
|
|
+ }
|
|
|
+
|
|
|
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
|
+
|
|
|
+ if (uMsg == WM_LBUTTONDOWN)
|
|
|
+ {
|
|
|
+ int hitType = HitTestVideoBorder(pt, borderRect);
|
|
|
+ if (hitType == HTNOWHERE)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_isDraggingVideoBorder = true;
|
|
|
+ m_videoBorderHitType = hitType;
|
|
|
+ m_videoBorderDragStartPt = pt;
|
|
|
+ m_videoBorderDragStartRect = m_videoBorderRect;
|
|
|
+
|
|
|
+ ::SetCapture(m_pMainWnd->GetHWND());
|
|
|
+ setCursorByHit(hitType);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uMsg == WM_MOUSEMOVE)
|
|
|
+ {
|
|
|
+ if (!m_isDraggingVideoBorder)
|
|
|
+ {
|
|
|
+ int hitType = HitTestVideoBorder(pt, borderRect);
|
|
|
+ if (hitType == HTNOWHERE)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ setCursorByHit(hitType);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ int dx = MulDiv(pt.x - m_videoBorderDragStartPt.x, kVideoPreviewWidth, imageWidth);
|
|
|
+ int dy = MulDiv(pt.y - m_videoBorderDragStartPt.y, kVideoPreviewHeight, imageHeight);
|
|
|
+
|
|
|
+ RECT newRect = m_videoBorderDragStartRect;
|
|
|
+
|
|
|
+ if (m_videoBorderHitType == HTLEFT || m_videoBorderHitType == HTTOPLEFT || m_videoBorderHitType == HTBOTTOMLEFT)
|
|
|
+ {
|
|
|
+ int maxLeft = static_cast<int>(m_videoBorderDragStartRect.right) - kVideoMinWidth;
|
|
|
+ int left = std::max(0, std::min(static_cast<int>(m_videoBorderDragStartRect.left) + dx, maxLeft));
|
|
|
+ newRect.left = static_cast<LONG>(left);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_videoBorderHitType == HTRIGHT || m_videoBorderHitType == HTTOPRIGHT || m_videoBorderHitType == HTBOTTOMRIGHT)
|
|
|
+ {
|
|
|
+ int minRight = static_cast<int>(m_videoBorderDragStartRect.left) + kVideoMinWidth;
|
|
|
+ int right = std::max(minRight, std::min(static_cast<int>(m_videoBorderDragStartRect.right) + dx, kVideoPreviewWidth));
|
|
|
+ newRect.right = static_cast<LONG>(right);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_videoBorderHitType == HTTOP || m_videoBorderHitType == HTTOPLEFT || m_videoBorderHitType == HTTOPRIGHT)
|
|
|
+ {
|
|
|
+ int maxTop = static_cast<int>(m_videoBorderDragStartRect.bottom) - kVideoMinHeight;
|
|
|
+ int top = std::max(0, std::min(static_cast<int>(m_videoBorderDragStartRect.top) + dy, maxTop));
|
|
|
+ newRect.top = static_cast<LONG>(top);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_videoBorderHitType == HTBOTTOM || m_videoBorderHitType == HTBOTTOMLEFT || m_videoBorderHitType == HTBOTTOMRIGHT)
|
|
|
+ {
|
|
|
+ int minBottom = static_cast<int>(m_videoBorderDragStartRect.top) + kVideoMinHeight;
|
|
|
+ int bottom = std::max(minBottom, std::min(static_cast<int>(m_videoBorderDragStartRect.bottom) + dy, kVideoPreviewHeight));
|
|
|
+ newRect.bottom = static_cast<LONG>(bottom);
|
|
|
+ }
|
|
|
+
|
|
|
+ m_videoBorderRect = newRect;
|
|
|
+
|
|
|
+ ::PostMessage(m_pMainWnd->GetHWND(), WM_AI_XUEXI_UPDATE, 0, 0);
|
|
|
+ setCursorByHit(m_videoBorderHitType);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uMsg == WM_LBUTTONUP)
|
|
|
+ {
|
|
|
+ if (!m_isDraggingVideoBorder)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_isDraggingVideoBorder = false;
|
|
|
+ ::ReleaseCapture();
|
|
|
+ SaveVideoBorderRect();
|
|
|
+ ::PostMessage(m_pMainWnd->GetHWND(), WM_AI_XUEXI_UPDATE, 0, 0);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|