Program Listing for File showcontrolwidget.cpp¶
↰ Return to documentation for file (src/widget/showcontrolwidget.cpp
)
#include <QKeyEvent>
#include <QListIterator>
#include <QListWidget>
#include <QModelIndex>
#include <QRegExp>
#include <QSettings>
#include <QTime>
#include "dialog/preferencesdialog.h"
#include "dialog/editeventdialog.h"
#include "showcontrolwidget.h"
#include "ui_showcontrolwidget.h"
#include "controller/showcontroller.h"
namespace PixelMaestroStudio {
QString ShowControlWidget::time_format = QStringLiteral("hh:mm:ss.zzz");
ShowControlWidget::ShowControlWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ShowControlWidget),
maestro_control_widget_(*dynamic_cast<MaestroControlWidget*>(parent)) {
ui->setupUi(this);
// Capture key presses
qApp->installEventFilter(this);
show_timer_.start();
connect(ui->eventQueueWidget->model(), &QAbstractItemModel::rowsMoved, this, &ShowControlWidget::on_eventQueueWidget_rowsMoved);
}
void ShowControlWidget::add_event_to_history(uint8_t *cue) {
ui->eventHistoryWidget->addItem(CueInterpreter::interpret_cue(cue));
// Convert the Cue into an actual byte array, which we'll store in the Event History for later use.
uint32_t cue_size = maestro_control_widget_.cue_controller_->get_cue_size(cue);
QVector<uint8_t> cue_vector(cue_size);
for (uint16_t byte = 0; byte < cue_size; byte++) {
cue_vector[byte] = cue[byte];
}
event_history_.push_back(cue_vector);
// Remove all but the last XX events
QSettings settings;
if (event_history_.size() >= settings.value(PreferencesDialog::event_history_max, 200).toInt()) {
ui->eventHistoryWidget->takeItem(0);
event_history_.remove(0);
}
}
bool ShowControlWidget::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* key_event = dynamic_cast<QKeyEvent*>(event);
// Delete queued events only when when Event queue has focus
if (watched == ui->eventQueueWidget) {
if (key_event->key() == Qt::Key_Delete) {
on_removeEventButton_clicked();
return true;
}
}
}
return QObject::eventFilter(watched, event);
}
void ShowControlWidget::initialize() {
// Disable controls by default
set_show_controls_enabled(false);
// Setup timer
show_timer_.setTimerType(Qt::CoarseTimer);
show_timer_.setInterval(TIMER_INTERVAL_);
connect(&show_timer_, SIGNAL(timeout()), this, SLOT(timer_refresh()));
// Initialize ShowController
if (show_controller_ == nullptr) {
show_controller_ = new ShowController();
}
else {
show_controller_->clear();
}
on_clearHistoryButton_clicked();
on_clearQueueButton_clicked();
}
bool ShowControlWidget::get_maestro_locked() const {
return maestro_locked_;
}
void ShowControlWidget::move_event(int current_index, int target_index) {
QListWidgetItem* item = ui->eventQueueWidget->takeItem(current_index);
show_controller_->move(current_index, target_index);
ui->eventQueueWidget->insertItem(target_index, item);
ui->eventQueueWidget->setCurrentRow(target_index);
}
void ShowControlWidget::on_addEventButton_clicked() {
for (QModelIndex index : ui->eventHistoryWidget->selectionModel()->selectedIndexes()) {
QTime time = ui->eventTimeEdit->time();
show_controller_->add_event(
(uint32_t)time.msecsSinceStartOfDay(),
(uint8_t*)event_history_.at(index.row()).data()
);
ui->eventQueueWidget->addItem(
time.toString(time_format) +
QString(": ") +
ui->eventHistoryWidget->item(index.row())->text()
);
}
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size(),
true
)
);
}
void ShowControlWidget::on_clearHistoryButton_clicked() {
ui->eventHistoryWidget->clear();
event_history_.clear();
}
void ShowControlWidget::on_clearQueueButton_clicked() {
ui->eventQueueWidget->clear();
show_controller_->get_events()->clear();
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
nullptr,
0,
false
)
);
}
void ShowControlWidget::on_enableCheckBox_toggled(bool checked) {
set_show_controls_enabled(checked);
if (checked) {
maestro_control_widget_.run_cue(
maestro_control_widget_.maestro_handler->set_show()
);
}
else {
maestro_control_widget_.run_cue(
maestro_control_widget_.maestro_handler->remove_show()
);
}
}
void ShowControlWidget::on_eventQueueWidget_itemDoubleClicked(QListWidgetItem *item) {
int row = ui->eventQueueWidget->row(item);
// Make sure the row is in the bounds of the Event queue
if (row > -1 && row < show_controller_->get_events()->size()) {
Event* event = &show_controller_->get_events()->data()[row];
EditEventDialog dialog(*event, this);
if (dialog.exec() == QDialog::Accepted) {
// Update the UI and actual Show Event
item->setText(locale_.toString(event->get_time()) +
QString(": ") +
CueInterpreter::interpret_cue(event->get_cue()));
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size()
)
);
}
}
}
void ShowControlWidget::on_eventQueueWidget_rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) {
if (parent == destination) {
for (int i = start; i < end; i++) {
int dest_row = row;
if (dest_row >= show_controller_->get_events()->size()) {
dest_row = show_controller_->get_events()->size() - 1;
}
show_controller_->move(start, dest_row);
}
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size()
)
);
}
}
void ShowControlWidget::on_loopCheckBox_toggled(bool checked) {
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_looping(checked)
);
}
void ShowControlWidget::on_moveEventDownButton_clicked() {
QModelIndexList list = ui->eventQueueWidget->selectionModel()->selectedIndexes();
for (int i = list.size() - 1; i >= 0; i--) {
int current_index = list.at(i).row();
if (current_index != ui->eventQueueWidget->count() - 1) {
move_event(current_index, current_index + 1);
}
}
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size()
)
);
}
void ShowControlWidget::on_moveEventUpButton_clicked() {
QModelIndexList list = ui->eventQueueWidget->selectionModel()->selectedIndexes();
for (int i = 0; i < list.size(); i++) {
int current_index = list.at(i).row();
if (current_index != 0) {
move_event(current_index, current_index - 1);
}
}
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size()
)
);
}
void ShowControlWidget::on_removeEventButton_clicked() {
// Sort selected rows by index before removing them
QModelIndexList list = ui->eventQueueWidget->selectionModel()->selectedRows();
qSort(list.begin(), list.end(), qGreater<QModelIndex>());
for (QModelIndex index : list) {
show_controller_->remove_event(index.row());
ui->eventQueueWidget->takeItem(index.row());
}
// Re-initialize the Event list
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_events(
show_controller_->get_events()->data(),
show_controller_->get_events()->size(),
true
)
);
}
void ShowControlWidget::on_timingModeComboBox_currentIndexChanged(int index) {
maestro_control_widget_.run_cue(
maestro_control_widget_.show_handler->set_timing_mode(
(Show::TimingMode)index
)
);
// Enable loop checkbox if we're in relative mode
bool relative_mode = (Show::TimingMode)index == Show::TimingMode::Relative;
ui->loopCheckBox->setEnabled(relative_mode);
ui->relativeTimeLineEdit->setEnabled(relative_mode);
}
void ShowControlWidget::refresh() {
Show* show = maestro_control_widget_.get_maestro_controller()->get_maestro().get_show();
ui->enableCheckBox->blockSignals(true);
ui->enableCheckBox->setChecked(show != nullptr);
set_show_controls_enabled(show != nullptr);
ui->enableCheckBox->blockSignals(false);
if (show != nullptr) {
for (uint16_t i = 0; i < show->get_num_events(); i++) {
Event* event = show->get_event_at_index(i);
if (event != nullptr) {
// Check for Events before adding them to prevent duplicates
if (show_controller_->get_event_index(event) < 0) {
show_controller_->add_event(event->get_time(), event->get_cue());
QTime event_time = QTime::fromMSecsSinceStartOfDay(event->get_time());
ui->eventQueueWidget->addItem(
event_time.toString(time_format) +
QString(": ") +
CueInterpreter::interpret_cue(event->get_cue())
);
}
}
}
ui->timingModeComboBox->blockSignals(true);
ui->timingModeComboBox->setCurrentIndex((uint8_t)show->get_timing());
ui->timingModeComboBox->blockSignals(false);
ui->loopCheckBox->blockSignals(true);
ui->loopCheckBox->setChecked(show->get_looping());
ui->loopCheckBox->blockSignals(false);
ui->relativeTimeLineEdit->blockSignals(true);
ui->relativeTimeLineEdit->setEnabled(show->get_timing() == Show::TimingMode::Relative);
ui->relativeTimeLineEdit->blockSignals(false);
}
else {
ui->timingModeComboBox->blockSignals(true);
ui->timingModeComboBox->setCurrentIndex(0);
ui->timingModeComboBox->blockSignals(false);
ui->loopCheckBox->blockSignals(true);
ui->loopCheckBox->setChecked(false);
ui->loopCheckBox->blockSignals(false);
ui->relativeTimeLineEdit->blockSignals(true);
ui->relativeTimeLineEdit->setEnabled(false);
ui->relativeTimeLineEdit->blockSignals(false);
}
}
void ShowControlWidget::set_maestro_locked(bool locked) {
this->maestro_locked_ = locked;
}
void ShowControlWidget::timer_refresh() {
// Update 'Absolute Time' text box
uint absolute_time = (uint)maestro_control_widget_.get_maestro_controller()->get_total_elapsed_time();
ui->absoluteTimeLineEdit->setText(QTime::fromMSecsSinceStartOfDay(absolute_time).toString(time_format));
Show* show = maestro_control_widget_.get_maestro_controller()->get_maestro().get_show();
if (show == nullptr) return;
// If relative mode is enabled, calculate the time since the last Event
if (show->get_timing() == Show::TimingMode::Relative) {
uint relative_time = absolute_time - show->get_last_time();
ui->relativeTimeLineEdit->setText(QTime::fromMSecsSinceStartOfDay(relative_time).toString(time_format));
}
// Get the last event that ran, and if it differs from the Show's current index, update the Event Queue
if (last_event_time_ != show->get_last_time()) {
last_event_time_ = show->get_last_time();
// Darken events that have already ran
for (int i = 0; i < ui->eventQueueWidget->count(); i++) {
if (i < show->get_current_index()) {
ui->eventQueueWidget->item(i)->setTextColor(Qt::GlobalColor::darkGray);
}
else {
ui->eventQueueWidget->item(i)->setTextColor(Qt::GlobalColor::white);
}
}
// If live update triggers are enabled, send the last Event's queue to the DeviceControlWidget to be sent to remote devices
QSettings settings;
if (settings.value(PreferencesDialog::events_trigger_device_updates, false).toBool()) {
Event* event = show->get_event_at_index(show->get_current_index());
if (event != nullptr) {
CueController* cue_controller = &maestro_control_widget_.get_maestro_controller()->get_maestro().get_cue_controller();
maestro_control_widget_.device_control_widget_->run_cue(
event->get_cue(),
cue_controller->get_cue_size(event->get_cue())
);
}
}
maestro_control_widget_.set_refresh_needed(true);
}
}
void ShowControlWidget::set_show_controls_enabled(bool enabled) {
ui->timingModeLabel->setEnabled(enabled);
ui->timingModeComboBox->setEnabled(enabled);
ui->loopCheckBox->setEnabled(enabled);
ui->eventsGroupBox->setEnabled(enabled);
}
ShowControlWidget::~ShowControlWidget() {
qApp->removeEventFilter(this);
delete show_controller_;
delete ui;
}
}