RecordControlApplication/Menu.cpp
2024-08-11 20:26:42 -07:00

368 lines
11 KiB
C++
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Menu.h"
#include "Constant.h"
#include "DatabaseManager.h"
#include "Log.h"
#include "ui_Menu.h"
#include <QDateTime>
#include <QDesktopWidget>
#include <QListView>
#include <QTimer>
#define CONTENT_ROW 6 // 列表行
#define CONTENT_COLUMN 6 // 列表列
#define CONTENT_CELL_HEIGHT 56 // 单元格高度
Menu::Menu(QWidget* parent)
: QWidget(parent)
, FocusWindow()
, ui(new Ui::Menu)
{
ui->setupUi(this);
setAttribute(Qt::WA_WState_WindowOpacitySet);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
setWindowOpacity(0.5);
setFixedSize(800, 600);
ui->stackedWidget->setCurrentIndex(0);
ui->btnChannelSetting->setFocus();
QDesktopWidget* deskdop = QApplication::desktop();
QWidget::move((deskdop->width() - this->width()) / 2, (deskdop->height() - this->height()) / 2);
ui->cmbYear->setView(new QListView());
ui->cmbMonth->setView(new QListView());
ui->cmbDay->setView(new QListView());
// 设置ScrollArea为栅格布局
QGridLayout* layout = new QGridLayout(ui->scrollArea);
ui->scrollAreaWidgetContents->setLayout(layout);
db = DatabaseManager::getInstace();
if (!db->open())
return;
connect(ui->cmbYear, &QComboBox::currentTextChanged, [=](QString text) {
renderComboBoxMonth();
});
connect(ui->cmbMonth, &QComboBox::currentTextChanged, [=](QString text) {
renderComboBoxDay();
});
// 默认设置当前操作选择主通道
currentChannel = DatabaseManager::MainChannel;
QTimer::singleShot(200, [=] {
emit curChannelChanged(Constant::MainChannel);
});
}
Menu::~Menu()
{
delete ui;
delete db;
}
/**
* @brief 重写菜单show方法
*/
void Menu::show()
{
renderComboBoxYear();
getContents();
QWidget::show();
}
/**
* @brief 设置是否显示通道选择
* @param visible
*/
void Menu::setChannelSelectVisible(bool visible)
{
ui->widget_chnSelect->setVisible(visible);
}
/**
* @brief 渲染年份
*/
void Menu::renderComboBoxYear()
{
QStringList years = db->getAllYears(currentChannel);
ui->cmbYear->clear();
for (auto& str : years) {
ui->cmbYear->addItem(str);
}
ui->cmbYear->setCurrentIndex(0);
}
/**
* @brief 渲染月份
*/
void Menu::renderComboBoxMonth()
{
QString year = ui->cmbYear->currentText();
if (year.isEmpty()) {
return;
}
QStringList months = db->getAllMonths(currentChannel, year);
ui->cmbMonth->clear();
for (auto& str : months) {
ui->cmbMonth->addItem(str);
}
ui->cmbMonth->setCurrentIndex(0);
}
/**
* @brief 渲染天数
*/
void Menu::renderComboBoxDay()
{
QString year = ui->cmbYear->currentText();
QString month = ui->cmbMonth->currentText();
if (year.isEmpty() || year.isEmpty()) {
return;
}
QStringList days = db->getAllDays(currentChannel, year, month);
ui->cmbDay->clear();
for (auto& str : days) {
ui->cmbDay->addItem(str);
}
ui->cmbDay->setCurrentIndex(0);
}
/**
* @brief 获取数据
*/
void Menu::getContents()
{
QVariantMap params;
params["channel"] = currentChannel;
params["year"] = ui->cmbYear->currentText();
params["month"] = ui->cmbMonth->currentText();
params["day"] = ui->cmbDay->currentText();
contentList = db->get(params);
renderContents();
}
/**
* @brief 将视频名称列表渲染成一堆按钮放到ScrollArea中6*6
*/
void Menu::renderContents()
{
QGridLayout* layout = qobject_cast<QGridLayout*>(ui->scrollAreaWidgetContents->layout());
// 清除原来的控件防止内存泄漏
QList<QWidget*> widgets = ui->scrollAreaWidgetContents->findChildren<QWidget*>();
for (QWidget* w : widgets) {
delete w;
}
// 重新生成若干个按钮
for (int i = 0; i < contentList.length(); i++) {
// 文件名格式: yyyyMMddhhmmss.mp4只将时分秒显示到界面上
DatabaseManager::File file = contentList.at(i);
QPushButton* btn = new QPushButton(file.time, ui->scrollArea);
btn->setProperty("name", file.filename);
btn->setMinimumHeight(CONTENT_CELL_HEIGHT);
btn->setStyleSheet("QPushButton{border-radius: 5px;}");
btn->setCheckable(true);
btn->setAutoExclusive(true);
btn->setObjectName(QString("btn_video_%1").arg(i));
int row = i / CONTENT_COLUMN;
int column = i % CONTENT_COLUMN;
layout->addWidget(btn, row, column);
}
// 少于36个用空的widget占位置
if (contentList.length() < CONTENT_ROW * CONTENT_COLUMN) {
int lastRow = (contentList.length() - 1) / CONTENT_COLUMN;
int lastColum = (contentList.length() - 1) % CONTENT_COLUMN;
for (int i = lastRow; i < CONTENT_ROW; i++) {
for (int j = 0; j < CONTENT_COLUMN; j++) {
if (i == lastRow && j <= lastColum) {
continue;
}
QWidget* widget = new QWidget(ui->scrollArea);
widget->setMinimumHeight(CONTENT_CELL_HEIGHT);
layout->addWidget(widget, i, j);
}
}
}
}
/**
* @brief 移动
* @param direction
*/
void Menu::move(Direction direction)
{
QWidget* focusWidget = QApplication::focusWidget();
// 当前焦点是否在展开后的ComboBox上
bool isCmbPopup = (strcmp(focusWidget->metaObject()->className(), "QListView") == 0);
// 下拉框展开,则只进行上下选择
if (isCmbPopup) {
// 随便赋值一个不影响功能的按键
Qt::Key key = Qt::Key_Right;
if (direction == Up) {
key == Qt::Key_Up;
} else if (direction == Down) {
key == Qt::Key_Down;
}
QKeyEvent pressEvent(QEvent::KeyPress, key, Qt::NoModifier);
QApplication::sendEvent(focusWidget, &pressEvent);
QKeyEvent releaseEvent(QEvent::KeyRelease, key, Qt::NoModifier);
QApplication::sendEvent(focusWidget, &releaseEvent);
} else {
focusNext(direction);
focusWidget = QApplication::focusWidget();
int drawedHeight = focusWidget->visibleRegion().boundingRect().height();
int height = focusWidget->height();
// 绘制的高度小于实际高度,则表示控件显示不完全
if (drawedHeight < height) {
ui->scrollArea->ensureWidgetVisible(focusWidget);
}
if (focusWidget == ui->btnChannelSetting) {
ui->btnChannelSetting->setChecked(true);
ui->stackedWidget->setCurrentIndex(0);
} else if (focusWidget == ui->btnPlayback) {
ui->btnPlayback->setChecked(true);
ui->stackedWidget->setCurrentIndex(1);
}
}
}
/**
* @brief 确认
*/
void Menu::confirm()
{
int index = ui->stackedWidget->currentIndex();
QWidget* focusWidget = QApplication::focusWidget();
switch (index) {
// 通道设置界面
case 0: {
QPushButton* btn = qobject_cast<QPushButton*>(focusWidget);
btn->setChecked(true);
if (btn == ui->btn_hdmi_1) {
emit btnHdmi1Checked();
} else if (btn == ui->btn_hdmi_2) {
emit btnHdmi2Checked();
} else if (btn == ui->btn_vga_1) {
emit btnVga1Checked();
} else if (btn == ui->btn_vga_2) {
emit btnVga2Checked();
}
break;
}
// 回放界面
case 1: {
// 通道选择时按下确认
if (focusWidget == ui->btn_channel_1 || focusWidget == ui->btn_channel_2) {
QPushButton* btn = qobject_cast<QPushButton*>(focusWidget);
btn->setChecked(true);
if (btn == ui->btn_channel_1) {
currentChannel = DatabaseManager::MainChannel;
emit curChannelChanged(Constant::MainChannel);
} else {
currentChannel = DatabaseManager::SecondaryChannel;
emit curChannelChanged(Constant::SecondaryChannel);
}
renderComboBoxYear();
}
// 下拉框未展开时按下确认
else if (strcmp(focusWidget->metaObject()->className(), "QComboBox") == 0) {
QComboBox* cmb = qobject_cast<QComboBox*>(focusWidget);
cmb->showPopup();
}
// 下拉框展开时按下确认
else if (strcmp(focusWidget->metaObject()->className(), "QListView") == 0) {
// QComboBox的层级
// QComboBox
// |- QComboBoxPrivateContainer(Popup widget)
// |- QListView(or QListWidget)
// |-QViewPort(Child of QListView)
QComboBox* cmb = static_cast<QComboBox*>(focusWidget->parent()->parent());
if (cmb) {
cmb->hidePopup();
}
}
// 选择视频时按下确认
else if (focusWidget->objectName().contains("btn_video")) {
QPushButton* btn = qobject_cast<QPushButton*>(focusWidget);
btn->setChecked(true);
QString filename = btn->property("name").toString();
emit btnVideoClicked(filename);
currentFilename = filename;
}
// 确认按钮按下确认
else if (focusWidget->objectName() == "btn_done") {
getContents();
}
break;
}
default:
break;
}
}
/**
* @brief 点击查找当前列表中的上一个视频和下一个视频
*/
void Menu::clickVideo(QString type)
{
getContents();
int index = -1;
for (int i = 0; i < contentList.length(); i++) {
DatabaseManager::File file = contentList[i];
if (file.filename == currentFilename) {
index = i;
break;
}
}
QString filename;
// 上一个视频
if (type == "previous") {
if (index == 0) {
emit btnVideoClicked("first");
return;
}
filename = contentList[index - 1].filename;
}
// 下一个视频
else {
if (index == contentList.length() - 1) {
emit btnVideoClicked("last");
return;
}
filename = contentList[index + 1].filename;
}
filename = contentList[index + 1].filename;
emit btnVideoClicked(filename);
QString h = filename.mid(8, 2);
QString m = filename.mid(10, 2);
QString s = filename.mid(12, 2);
QString str = QString("%1:%2:%3").arg(h).arg(m).arg(s);
// 选中要播放的按钮
QList<QPushButton*> btns = ui->scrollArea->findChildren<QPushButton*>();
for (QPushButton* btn : btns) {
if (btn->text() == str) {
btn->setChecked(true);
}
}
}
/**
* @brief 遍历当前窗体可以获取焦点的所有控件
*/
QList<QWidget*> Menu::getAllFocusabelWidget()
{
QList<QWidget*> list = findChildren<QWidget*>();
QList<QWidget*> result;
for (int i = 0; i < list.length(); i++) {
QWidget* w = list.at(i);
if (w->focusPolicy() == Qt::NoFocus || !w->isVisible())
continue;
else {
result.push_back(w);
}
}
return result;
}