From: Steinar H. Gunderson Date: Tue, 2 May 2023 17:27:41 +0000 (+0200) Subject: Make explicit offense/defense markers, by clicking. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=32927e6c7a628fa9a3bb06c7d806601103a44e34;p=pkanalytics Make explicit offense/defense markers, by clicking. --- diff --git a/clickable_label.h b/clickable_label.h new file mode 100644 index 0000000..cc82168 --- /dev/null +++ b/clickable_label.h @@ -0,0 +1,26 @@ +#ifndef _CLICKABLE_LABEL_H +#define _CLICKABLE_LABEL_H 1 + +// Just like a normal QLabel, except that it can also emit a clicked signal. + +#include + +class QMouseEvent; + +class ClickableLabel : public QLabel { + Q_OBJECT + +public: + ClickableLabel(QWidget *parent) : QLabel(parent) {} + +signals: + void clicked(); + +protected: + void mousePressEvent(QMouseEvent *event) override + { + emit clicked(); + } +}; + +#endif // !defined(_CLICKABLE_LABEL_H) diff --git a/events.cpp b/events.cpp index bce2625..0e3a62d 100644 --- a/events.cpp +++ b/events.cpp @@ -230,13 +230,18 @@ EventsModel::Status EventsModel::get_status_at(uint64_t t) Status s; s.our_score = 0; s.their_score = 0; - s.offense = true; + s.offense = false; + s.defense = false; s.stoppage = false; s.should_pull = true; uint64_t last_gained_possession = 0; uint64_t last_stoppage = 0; uint64_t time_spent_in_stoppage = 0; unsigned num_touches = 0; + + auto set_offense = [&s] { s.offense = true; s.defense = false; }; + auto set_defense = [&s] { s.offense = false; s.defense = true; }; + for (const Event &e : events) { if (e.t > t) { break; @@ -250,14 +255,20 @@ EventsModel::Status EventsModel::get_status_at(uint64_t t) s.should_pull = false; } + if (e.type == "set_offense") { + set_offense(); + } else if (e.type == "set_defense") { + set_defense(); + } + if (e.type == "goal") { ++s.our_score; - s.offense = false; + set_defense(); num_touches = 0; } if (e.type == "their_goal") { ++s.their_score; - s.offense = true; + set_offense(); num_touches = 0; } if (e.type == "catch") { @@ -269,17 +280,17 @@ EventsModel::Status EventsModel::get_status_at(uint64_t t) } if (e.type == "interception") { num_touches = 1; - s.offense = true; + set_offense(); last_gained_possession = e.t; time_spent_in_stoppage = 0; } if (e.type == "defense" || e.type == "their_throwaway") { - s.offense = true; + set_offense(); num_touches = 0; time_spent_in_stoppage = 0; } if (e.type == "drop" || e.type == "throwaway") { - s.offense = false; + set_defense(); num_touches = 0; } if (e.type == "stoppage") { diff --git a/events.h b/events.h index 62f1f7e..d3651e5 100644 --- a/events.h +++ b/events.h @@ -34,6 +34,7 @@ public: struct Status { unsigned our_score, their_score; bool offense; + bool defense; bool stoppage; bool should_pull; unsigned num_passes; diff --git a/main.cpp b/main.cpp index 46a0d1c..ab5cf5c 100644 --- a/main.cpp +++ b/main.cpp @@ -89,6 +89,7 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players) : events(even connect(ui->player_7, &QPushButton::clicked, [this]() { insert_event(7); }); // Offensive events + connect(ui->offense_label, &ClickableLabel::clicked, [this]() { insert_noplayer_event("set_offense"); }); connect(ui->catch_, &QPushButton::clicked, [this]() { set_current_event_type("catch"); }); connect(ui->throwaway, &QPushButton::clicked, [this]() { set_current_event_type("throwaway"); }); connect(ui->drop, &QPushButton::clicked, [this]() { set_current_event_type("drop"); }); @@ -99,6 +100,7 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players) : events(even connect(ui->pull_landed, &QPushButton::clicked, [this]() { insert_noplayer_event("pull_landed"); }); // Defensive events (TODO add more) + connect(ui->defense_label, &ClickableLabel::clicked, [this]() { insert_noplayer_event("set_defense"); }); connect(ui->their_throwaway, &QPushButton::clicked, [this]() { insert_noplayer_event("their_throwaway"); }); connect(ui->their_goal, &QPushButton::clicked, [this]() { insert_noplayer_event("their_goal"); }); connect(ui->their_pull, &QPushButton::clicked, [this]() { insert_noplayer_event("their_pull"); }); @@ -226,8 +228,16 @@ void MainWindow::update_status(uint64_t t) { EventsModel::Status s = events->get_status_at(t); char buf[256]; + const char *offense = "not started"; + if (s.offense) { + assert(!s.defense); + offense = "offense"; + } else if (s.defense) { + offense = "defense"; + } + snprintf(buf, sizeof(buf), "%d–%d | %s | %d passes, %d sec possession", - s.our_score, s.their_score, s.offense ? "offense" : "defense", s.num_passes, s.possession_sec); + s.our_score, s.their_score, offense, s.num_passes, s.possession_sec); if (s.stoppage_sec > 0) { char buf2[256]; snprintf(buf2, sizeof(buf2), "%s (plus %d sec stoppage)", buf, s.stoppage_sec); @@ -318,17 +328,17 @@ void MainWindow::update_action_buttons(uint64_t t) ui->offensive_soft_minus->setEnabled(s.offense && has_selection_with_player); // TODO: be stricter - ui->pull->setEnabled(!s.offense && s.should_pull && has_selection_with_player); - ui->pull_landed->setEnabled(!s.offense && has_selection_with_player); - - ui->interception->setEnabled(!s.offense && has_selection_with_player); - ui->their_throwaway->setEnabled(!s.offense); - ui->our_defense->setEnabled(!s.offense && has_selection_with_player); - ui->their_goal->setEnabled(!s.offense); - ui->defensive_soft_plus->setEnabled(!s.offense && has_selection_with_player); - ui->defensive_soft_minus->setEnabled(!s.offense && has_selection_with_player); + ui->pull->setEnabled(s.defense && s.should_pull && has_selection_with_player); + ui->pull_landed->setEnabled(s.defense && has_selection_with_player); + + ui->interception->setEnabled(s.defense && has_selection_with_player); + ui->their_throwaway->setEnabled(s.defense); + ui->our_defense->setEnabled(s.defense && has_selection_with_player); + ui->their_goal->setEnabled(s.defense); + ui->defensive_soft_plus->setEnabled(s.defense && has_selection_with_player); + ui->defensive_soft_minus->setEnabled(s.defense && has_selection_with_player); ui->their_pull->setEnabled(s.offense && s.should_pull); - ui->our_foul->setEnabled(!s.offense && has_selection_with_player); + ui->our_foul->setEnabled(s.defense && has_selection_with_player); } sqlite3 *open_db(const char *filename) diff --git a/mainwindow.ui b/mainwindow.ui index 8bb414d..142c1a6 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -214,7 +214,7 @@ - + Offense @@ -305,7 +305,7 @@ - + Defense @@ -486,6 +486,11 @@
QVideoWidget
1 + + ClickableLabel + QLabel +
clickable_label.h
+
diff --git a/meson.build b/meson.build index a466413..0475a21 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ qt6deps = dependency('qt6', modules: ['Core', 'Gui', 'Widgets', 'Multimedia', 'M sqlite3dep = dependency('sqlite3') qt_files = qt6.preprocess( - moc_headers: ['mainwindow.h'], + moc_headers: ['mainwindow.h', 'clickable_label.h'], ui_files: ['mainwindow.ui'], dependencies: qt6deps)