Merge pull request #384 from AttorneyOnline/feature/timerclock

Countdown timer
This commit is contained in:
oldmud0 2021-01-19 10:02:31 -06:00 committed by GitHub
commit e097df09ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 6 deletions

View File

@ -29,6 +29,7 @@
#include <QScreen>
#include <QStringList>
#include <QTextStream>
#include <QTime>
#include <QElapsedTimer>
@ -66,6 +67,9 @@ public:
void call_settings_menu();
void call_announce_menu(Courtroom *court);
qint64 latency = 0;
QString window_title;
/////////////////server metadata//////////////////
bool yellow_text_enabled = false;

29
include/aoclocklabel.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef AOCLOCKLABEL_H
#define AOCLOCKLABEL_H
#include <QLabel>
#include <QBasicTimer>
#include <QTimerEvent>
#include <QTime>
#include <QDebug>
class AOClockLabel : public QLabel {
Q_OBJECT
public:
AOClockLabel(QWidget *parent);
void start();
void start(int msecs);
void set(int msecs, bool update_text = false);
void pause();
void stop();
protected:
void timerEvent(QTimerEvent *event) override;
private:
QBasicTimer timer;
QTime target_time;
};
#endif // AOCLOCKLABEL_H

View File

@ -5,6 +5,7 @@
#include "aoblipplayer.h"
#include "aobutton.h"
#include "aocharbutton.h"
#include "aoclocklabel.h"
#include "aoemotebutton.h"
#include "aoevidencebutton.h"
#include "aoevidencedisplay.h"
@ -55,7 +56,7 @@
#include <QScrollBar>
#include <QTextBoundaryFinder>
#include <QTextCharFormat>
//#include <QRandomGenerator>
#include <QElapsedTimer>
#include <algorithm>
#include <stack>
@ -300,11 +301,18 @@ public:
void check_connection_received();
void start_clock(int id);
void start_clock(int id, qint64 msecs);
void set_clock(int id, qint64 msecs);
void pause_clock(int id);
void stop_clock(int id);
void set_clock_visibility(int id, bool visible);
qint64 pong();
// Truncates text so it fits within theme-specified boundaries and sets the tooltip to the full string
void truncate_label_text(QWidget* p_widget, QString p_identifier);
~Courtroom();
private:
AOApplication *ao_app;
@ -357,11 +365,16 @@ private:
QQueue<QStringList> chatmessage_queue;
// triggers ping_server() every 60 seconds
// triggers ping_server() every 45 seconds
QTimer *keepalive_timer;
// determines how fast messages tick onto screen
QTimer *chat_tick_timer;
// count up timer to check how long it took for us to get a response from ping_server()
QElapsedTimer ping_timer;
bool is_pinging = false;
// int chat_tick_interval = 60;
// which tick position(character in chat message) we are at
int tick_pos = 0;
@ -619,6 +632,9 @@ private:
StickerLayer *ui_vp_sticker;
static const int max_clocks = 5;
AOClockLabel *ui_clock[max_clocks];
AOButton *ui_pair_button;
QListWidget *ui_pair_list;
QSpinBox *ui_pair_offset_spinbox;

59
src/aoclocklabel.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "aoclocklabel.h"
AOClockLabel::AOClockLabel(QWidget *parent) : QLabel(parent) {}
void AOClockLabel::start()
{
timer.start(1000 / 60, this);
}
void AOClockLabel::start(int msecs)
{
this->set(msecs);
this->start();
}
void AOClockLabel::set(int msecs, bool update_text)
{
target_time = QTime::currentTime().addMSecs(msecs);
if (update_text)
{
if (QTime::currentTime() >= target_time)
{
this->setText("00:00:00.000");
}
else
{
QTime timeleft = QTime(0,0).addMSecs(QTime::currentTime().msecsTo(target_time));
QString timestring = timeleft.toString("hh:mm:ss.zzz");
this->setText(timestring);
}
}
}
void AOClockLabel::pause()
{
timer.stop();
}
void AOClockLabel::stop()
{
this->setText("00:00:00.000");
timer.stop();
}
void AOClockLabel::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timer.timerId()) {
if (QTime::currentTime() >= target_time)
{
this->stop();
return;
}
QTime timeleft = QTime(0,0).addMSecs(QTime::currentTime().msecsTo(target_time));
QString timestring = timeleft.toString("hh:mm:ss.zzz");
this->setText(timestring);
} else {
QWidget::timerEvent(event);
}
}

View File

@ -161,7 +161,6 @@ void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
void AOMusicPlayer::set_looping(bool toggle, int channel)
{
qDebug() << "Setting looping for channel" << channel << "to" << toggle;
m_looping = toggle;
if (!m_looping) {
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)

View File

@ -12,7 +12,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000));
keepalive_timer = new QTimer(this);
keepalive_timer->start(60000);
keepalive_timer->start(45000);
chat_tick_timer = new QTimer(this);
@ -120,6 +120,12 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_music_name = new ScrollText(ui_music_display);
ui_music_name->setText(tr("None"));
ui_music_name->setAttribute(Qt::WA_TransparentForMouseEvents);
for (int i = 0; i < max_clocks; i++) {
ui_clock[i] = new AOClockLabel(this);
ui_clock[i]->setAttribute(Qt::WA_TransparentForMouseEvents);
ui_clock[i]->hide();
}
ui_ic_chat_name = new QLineEdit(this);
ui_ic_chat_name->setFrame(false);
@ -663,6 +669,10 @@ void Courtroom::set_widgets()
ui_music_display->load_image("music_display", "");
for (int i = 0; i < max_clocks; i++) {
set_size_and_pos(ui_clock[i], "clock_" + QString::number(i));
}
if (is_ao2_bg) {
set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message");
// set_size_and_pos(ui_vp_chatbox, "ao2_chatbox");
@ -1016,6 +1026,9 @@ void Courtroom::set_fonts(QString p_char)
set_font(ui_area_list, "", "area_list", p_char);
set_font(ui_music_name, "", "music_name", p_char);
for (int i = 0; i < max_clocks; i++)
set_font(ui_clock[i], "", "clock_" + QString::number(i), p_char);
set_dropdowns();
}
@ -5266,10 +5279,21 @@ void Courtroom::on_switch_area_music_clicked()
void Courtroom::ping_server()
{
ping_timer.start();
is_pinging = true;
ao_app->send_server_packet(
new AOPacket("CH#" + QString::number(m_cid) + "#%"));
}
qint64 Courtroom::pong()
{
if (!is_pinging)
return -1;
is_pinging = false;
return ping_timer.elapsed();
}
void Courtroom::on_casing_clicked()
{
if (ao_app->casing_alerts_enabled) {
@ -5309,6 +5333,54 @@ void Courtroom::announce_case(QString title, bool def, bool pro, bool jud,
}
}
void Courtroom::start_clock(int id)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->start();
}
}
void Courtroom::start_clock(int id, qint64 msecs)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->start(static_cast<int>(msecs));
}
}
void Courtroom::set_clock(int id, qint64 msecs)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->set(static_cast<int>(msecs), true);
}
}
void Courtroom::pause_clock(int id)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->pause();
}
}
void Courtroom::stop_clock(int id)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->stop();
}
}
void Courtroom::set_clock_visibility(int id, bool visible)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
{
ui_clock[id]->setVisible(visible);
}
}
void Courtroom::truncate_label_text(QWidget *p_widget, QString p_identifier)
{
QString filename = "courtroom_design.ini";

View File

@ -260,7 +260,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
courtroom_loaded = false;
QString window_title = tr("Attorney Online 2");
window_title = tr("Attorney Online 2");
int selected_server = w_lobby->get_selected_server();
QString server_address = "", server_name = "";
@ -604,6 +604,60 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
f_contents.at(4) == "1",
f_contents.at(5) == "1");
}
else if (header == "TI") { // Timer packet
if (!courtroom_constructed || f_contents.size() < 2)
goto end;
// Timer ID is reserved as argument 0
int id = f_contents.at(0).toInt();
// Type 0 = start/resume/sync timer at time
// Type 1 = pause timer at time
// Type 2 = show timer
// Type 3 = hide timer
int type = f_contents.at(1).toInt();
if (type == 0 || type == 1)
{
if (f_contents.size() < 2)
goto end;
// The time as displayed on the clock, in milliseconds.
// If the number received is negative, stop the timer.
qint64 timer_value = f_contents.at(2).toLongLong();
qDebug() << "timer:" << timer_value;
if (timer_value > 0)
{
if (type == 0)
{
timer_value -= latency / 2;
w_courtroom->start_clock(id, timer_value);
}
else
{
w_courtroom->pause_clock(id);
w_courtroom->set_clock(id, timer_value);
}
}
else
{
w_courtroom->stop_clock(id);
}
}
else if (type == 2)
w_courtroom->set_clock_visibility(id, true);
else if (type == 3)
w_courtroom->set_clock_visibility(id, false);
}
else if (header == "CHECK") {
if (!courtroom_constructed)
goto end;
qint64 ping_time = w_courtroom->pong();
qDebug() << "ping:" << ping_time;
if (ping_time != -1)
latency = ping_time;
}
end: