forked from eden-emu/eden
Compare commits
3 commits
8c75831911
...
db49d1a20c
Author | SHA1 | Date | |
---|---|---|---|
db49d1a20c | |||
0636f93e16 | |||
5c8d72dddd |
11 changed files with 250 additions and 137 deletions
|
@ -13,6 +13,9 @@
|
|||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include "play_time_manager.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace PlayTime {
|
||||
|
||||
namespace {
|
||||
|
@ -164,4 +167,37 @@ void PlayTimeManager::ResetProgramPlayTime(u64 program_id) {
|
|||
Save();
|
||||
}
|
||||
|
||||
std::string PlayTimeManager::GetReadablePlayTime(u64 time_seconds) {
|
||||
if (time_seconds == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto time_minutes = std::max(static_cast<double>(time_seconds) / 60.0, 1.0);
|
||||
const auto time_hours = static_cast<double>(time_seconds) / 3600.0;
|
||||
const bool is_minutes = time_minutes < 60.0;
|
||||
|
||||
if (is_minutes) {
|
||||
return fmt::format("{:.0f} m", time_minutes);
|
||||
} else {
|
||||
const bool has_remainder = time_seconds % 60 != 0;
|
||||
if (has_remainder) {
|
||||
return fmt::format("{:.1f} h", time_hours);
|
||||
} else {
|
||||
return fmt::format("{:.0f} h", time_hours);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string PlayTimeManager::GetPlayTimeHours(u64 time_seconds) {
|
||||
return fmt::format("{}", time_seconds / 3600);
|
||||
}
|
||||
|
||||
std::string PlayTimeManager::GetPlayTimeMinutes(u64 time_seconds) {
|
||||
return fmt::format("{}", (time_seconds % 3600) / 60);
|
||||
}
|
||||
|
||||
std::string PlayTimeManager::GetPlayTimeSeconds(u64 time_seconds) {
|
||||
return fmt::format("{}", time_seconds % 60);
|
||||
}
|
||||
|
||||
} // namespace PlayTime
|
||||
|
|
|
@ -38,6 +38,11 @@ public:
|
|||
void Start();
|
||||
void Stop();
|
||||
|
||||
static std::string GetReadablePlayTime(u64 time_seconds);
|
||||
static std::string GetPlayTimeHours(u64 time_seconds);
|
||||
static std::string GetPlayTimeMinutes(u64 time_seconds);
|
||||
static std::string GetPlayTimeSeconds(u64 time_seconds);
|
||||
|
||||
private:
|
||||
void AutoTimestamp(std::stop_token stop_token);
|
||||
void Save();
|
||||
|
|
|
@ -27,9 +27,6 @@ add_library(qt_common STATIC
|
|||
qt_rom_util.h qt_rom_util.cpp
|
||||
qt_applet_util.h qt_applet_util.cpp
|
||||
qt_progress_dialog.h qt_progress_dialog.cpp
|
||||
qt_playtime_manager.cpp
|
||||
qt_playtime_manager.h
|
||||
|
||||
)
|
||||
|
||||
create_target_directory_groups(qt_common)
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_playtime_manager.h"
|
||||
|
||||
namespace QtCommon::PlayTimeManager {
|
||||
|
||||
QString ReadablePlayTime(qulonglong time_seconds) {
|
||||
if (time_seconds == 0) {
|
||||
return {};
|
||||
}
|
||||
const auto time_minutes = std::max(static_cast<double>(time_seconds) / 60, 1.0);
|
||||
const auto time_hours = static_cast<double>(time_seconds) / 3600;
|
||||
const bool is_minutes = time_minutes < 60;
|
||||
const char* unit = is_minutes ? "m" : "h";
|
||||
const auto value = is_minutes ? time_minutes : time_hours;
|
||||
|
||||
return QStringLiteral("%L1 %2")
|
||||
.arg(value, 0, 'f', !is_minutes && time_seconds % 60 != 0)
|
||||
.arg(QString::fromUtf8(unit));
|
||||
}
|
||||
|
||||
QString GetPlayTimeUnit(qulonglong time_seconds, TimeUnit unit) {
|
||||
switch (unit) {
|
||||
case TimeUnit::Hours: {
|
||||
const qulonglong hours = time_seconds / 3600;
|
||||
return QString::number(hours);
|
||||
}
|
||||
case TimeUnit::Minutes: {
|
||||
const qulonglong minutes = (time_seconds % 3600) / 60;
|
||||
return QString::number(minutes);
|
||||
}
|
||||
case TimeUnit::Seconds: {
|
||||
const qulonglong seconds = time_seconds % 60;
|
||||
return QString::number(seconds);
|
||||
}
|
||||
default:
|
||||
return QStringLiteral("0");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QtCommon::PlayTimeManager
|
|
@ -1,20 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace QtCommon::PlayTimeManager {
|
||||
|
||||
enum class TimeUnit {
|
||||
Hours,
|
||||
Minutes,
|
||||
Seconds
|
||||
};
|
||||
|
||||
// Converts a length of time in seconds into a readable format
|
||||
QString ReadablePlayTime(qulonglong time_seconds);
|
||||
|
||||
// Returns play time hours/minutes/seconds as a string
|
||||
QString GetPlayTimeUnit(qulonglong time_seconds, TimeUnit unit);
|
||||
|
||||
} // namespace QtCommon::PlayTimeManager
|
|
@ -201,6 +201,8 @@ add_executable(yuzu
|
|||
precompiled_headers.h
|
||||
startup_checks.cpp
|
||||
startup_checks.h
|
||||
set_play_time_dialog.cpp
|
||||
set_play_time_dialog.h
|
||||
util/clickable_label.cpp
|
||||
util/clickable_label.h
|
||||
util/controller_navigation.cpp
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "qt_common/qt_playtime_manager.h"
|
||||
#include "frontend_common/play_time_manager.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/util.h"
|
||||
|
||||
|
@ -241,7 +241,7 @@ public:
|
|||
|
||||
void setData(const QVariant& value, int role) override {
|
||||
qulonglong time_seconds = value.toULongLong();
|
||||
GameListItem::setData(QtCommon::PlayTimeManager::ReadablePlayTime(time_seconds), Qt::DisplayRole);
|
||||
GameListItem::setData(QString::fromStdString(PlayTime::PlayTimeManager::GetReadablePlayTime(time_seconds)), Qt::DisplayRole);
|
||||
GameListItem::setData(value, PlayTimeRole);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "set_play_time_dialog.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
#endif
|
||||
|
@ -2637,84 +2639,18 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, QtCommon::Game::GameListR
|
|||
}
|
||||
|
||||
void GMainWindow::OnGameListSetPlayTime(u64 program_id) {
|
||||
QDialog dialog(this);
|
||||
dialog.setWindowTitle(tr("Set Play Time Data"));
|
||||
dialog.setModal(true);
|
||||
|
||||
auto* layout = new QVBoxLayout(&dialog);
|
||||
auto* input_layout = new QHBoxLayout();
|
||||
auto* hours_edit = new QLineEdit(&dialog);
|
||||
auto* minutes_edit = new QLineEdit(&dialog);
|
||||
auto* seconds_edit = new QLineEdit(&dialog);
|
||||
|
||||
hours_edit->setValidator(new QIntValidator(0, 9999, hours_edit));
|
||||
minutes_edit->setValidator(new QIntValidator(0, 59, minutes_edit));
|
||||
seconds_edit->setValidator(new QIntValidator(0, 59, seconds_edit));
|
||||
|
||||
using QtCommon::PlayTimeManager::TimeUnit;
|
||||
const u64 current_play_time = play_time_manager->GetPlayTime(program_id);
|
||||
auto getTimeUnit = [current_play_time](TimeUnit unit) {
|
||||
return QtCommon::PlayTimeManager::GetPlayTimeUnit(current_play_time, unit);
|
||||
};
|
||||
|
||||
hours_edit->setText(getTimeUnit(TimeUnit::Hours));
|
||||
minutes_edit->setText(getTimeUnit(TimeUnit::Minutes));
|
||||
seconds_edit->setText(getTimeUnit(TimeUnit::Seconds));
|
||||
SetPlayTimeDialog dialog(this, current_play_time);
|
||||
|
||||
input_layout->addWidget(new QLabel(tr("Hours:"), &dialog));
|
||||
input_layout->addWidget(hours_edit);
|
||||
input_layout->addWidget(new QLabel(tr("Minutes:"), &dialog));
|
||||
input_layout->addWidget(minutes_edit);
|
||||
input_layout->addWidget(new QLabel(tr("Seconds:"), &dialog));
|
||||
input_layout->addWidget(seconds_edit);
|
||||
|
||||
layout->addLayout(input_layout);
|
||||
|
||||
auto* error_label = new QLabel(&dialog);
|
||||
error_label->setStyleSheet(QStringLiteral("QLabel { color : red; }"));
|
||||
error_label->setVisible(false);
|
||||
layout->addWidget(error_label);
|
||||
|
||||
auto* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
|
||||
layout->addWidget(button_box);
|
||||
|
||||
connect(button_box, &QDialogButtonBox::accepted, [&]() {
|
||||
const int hours = hours_edit->text().toInt();
|
||||
const int minutes = minutes_edit->text().toInt();
|
||||
const int seconds = seconds_edit->text().toInt();
|
||||
|
||||
if (hours < 0 || hours > 9999) {
|
||||
error_label->setText(tr("Hours must be between 0 and 9999."));
|
||||
error_label->setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (minutes < 0 || minutes > 59) {
|
||||
error_label->setText(tr("Minutes must be between 0 and 59."));
|
||||
error_label->setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seconds < 0 || seconds > 59) {
|
||||
error_label->setText(tr("Seconds must be between 0 and 59."));
|
||||
error_label->setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
u64 total_seconds = static_cast<u64>(hours) * 3600 + static_cast<u64>(minutes) * 60 + static_cast<u64>(seconds);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
const u64 total_seconds = dialog.GetTotalSeconds();
|
||||
play_time_manager->SetPlayTime(program_id, total_seconds);
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
|
||||
dialog.accept();
|
||||
});
|
||||
|
||||
connect(button_box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
|
||||
dialog.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GMainWindow::OnGameListRemovePlayTimeData(u64 program_id) {
|
||||
if (QMessageBox::question(this, tr("Remove Play Time Data"), tr("Reset play time?"),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
|
|
49
src/yuzu/set_play_time_dialog.cpp
Normal file
49
src/yuzu/set_play_time_dialog.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "yuzu/set_play_time_dialog.h"
|
||||
#include "frontend_common/play_time_manager.h"
|
||||
#include "ui_set_play_time_dialog.h"
|
||||
|
||||
SetPlayTimeDialog::SetPlayTimeDialog(QWidget* parent, u64 current_play_time)
|
||||
: QDialog(parent), ui{std::make_unique<Ui::SetPlayTimeDialog>()} {
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->hoursSpinBox->setValue(
|
||||
QString::fromStdString(PlayTime::PlayTimeManager::GetPlayTimeHours(current_play_time)).toInt());
|
||||
ui->minutesSpinBox->setValue(
|
||||
QString::fromStdString(PlayTime::PlayTimeManager::GetPlayTimeMinutes(current_play_time)).toInt());
|
||||
ui->secondsSpinBox->setValue(
|
||||
QString::fromStdString(PlayTime::PlayTimeManager::GetPlayTimeSeconds(current_play_time)).toInt());
|
||||
|
||||
connect(ui->hoursSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
&SetPlayTimeDialog::OnValueChanged);
|
||||
connect(ui->minutesSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
&SetPlayTimeDialog::OnValueChanged);
|
||||
connect(ui->secondsSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
&SetPlayTimeDialog::OnValueChanged);
|
||||
}
|
||||
|
||||
SetPlayTimeDialog::~SetPlayTimeDialog() = default;
|
||||
|
||||
u64 SetPlayTimeDialog::GetTotalSeconds() const {
|
||||
const u64 hours = static_cast<u64>(ui->hoursSpinBox->value());
|
||||
const u64 minutes = static_cast<u64>(ui->minutesSpinBox->value());
|
||||
const u64 seconds = static_cast<u64>(ui->secondsSpinBox->value());
|
||||
|
||||
return hours * 3600 + minutes * 60 + seconds;
|
||||
}
|
||||
|
||||
void SetPlayTimeDialog::OnValueChanged() {
|
||||
if (ui->errorLabel->isVisible()) {
|
||||
ui->errorLabel->setVisible(false);
|
||||
}
|
||||
|
||||
const u64 total_seconds = GetTotalSeconds();
|
||||
constexpr u64 max_reasonable_time = 9999ULL * 3600;
|
||||
|
||||
if (total_seconds > max_reasonable_time) {
|
||||
ui->errorLabel->setText(tr("Total play time reached maximum."));
|
||||
ui->errorLabel->setVisible(true);
|
||||
}
|
||||
}
|
27
src/yuzu/set_play_time_dialog.h
Normal file
27
src/yuzu/set_play_time_dialog.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Ui {
|
||||
class SetPlayTimeDialog;
|
||||
}
|
||||
|
||||
class SetPlayTimeDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SetPlayTimeDialog(QWidget* parent, u64 current_play_time);
|
||||
~SetPlayTimeDialog() override;
|
||||
|
||||
u64 GetTotalSeconds() const;
|
||||
|
||||
private:
|
||||
void OnValueChanged();
|
||||
|
||||
std::unique_ptr<Ui::SetPlayTimeDialog> ui;
|
||||
};
|
123
src/yuzu/set_play_time_dialog.ui
Normal file
123
src/yuzu/set_play_time_dialog.ui
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SetPlayTimeDialog</class>
|
||||
<widget class="QDialog" name="SetPlayTimeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Set Play Time Data</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="inputLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelHours">
|
||||
<property name="text">
|
||||
<string>Hours:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="hoursSpinBox">
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelMinutes">
|
||||
<property name="text">
|
||||
<string>Minutes:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="minutesSpinBox">
|
||||
<property name="maximum">
|
||||
<number>59</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSeconds">
|
||||
<property name="text">
|
||||
<string>Seconds:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="secondsSpinBox">
|
||||
<property name="maximum">
|
||||
<number>59</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel { color : red; }</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SetPlayTimeDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>129</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>74</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SetPlayTimeDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>129</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>74</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
Loading…
Add table
Add a link
Reference in a new issue