[Qt] Implement settings widgets that use abstract settings items
This commit is contained in:
parent
566d992f76
commit
4749ee1f03
|
@ -33,3 +33,7 @@ QWidget#navigationContainer {
|
||||||
QLabel#subLabel[type="warning"] {
|
QLabel#subLabel[type="warning"] {
|
||||||
color: $warning;
|
color: $warning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget#SettingsTab QWidget#settingsContainer QLabel#titleLabel {
|
||||||
|
color: $light2;
|
||||||
|
}
|
|
@ -9,12 +9,13 @@
|
||||||
|
|
||||||
#include "settings_widget_factory.h"
|
#include "settings_widget_factory.h"
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include "xenia/ui/qt/widgets/checkbox.h"
|
#include "xenia/ui/qt/settings/widgets/settings_checkbox.h"
|
||||||
|
#include "xenia/ui/qt/settings/widgets/settings_combobox.h"
|
||||||
|
#include "xenia/ui/qt/settings/widgets/settings_line_edit.h"
|
||||||
|
#include "xenia/ui/qt/settings/widgets/settings_slider.h"
|
||||||
#include "xenia/ui/qt/widgets/groupbox.h"
|
#include "xenia/ui/qt/widgets/groupbox.h"
|
||||||
#include "xenia/ui/qt/widgets/line_edit.h"
|
|
||||||
#include "xenia/ui/qt/widgets/push_button.h"
|
#include "xenia/ui/qt/widgets/push_button.h"
|
||||||
#include "xenia/ui/qt/widgets/scroll_area.h"
|
#include "xenia/ui/qt/widgets/scroll_area.h"
|
||||||
#include "xenia/ui/qt/widgets/slider.h"
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
@ -23,6 +24,12 @@ namespace qt {
|
||||||
const double kSubLabelSize = 6.5;
|
const double kSubLabelSize = 6.5;
|
||||||
const int kLineEditMaxWidth = 420;
|
const int kLineEditMaxWidth = 420;
|
||||||
|
|
||||||
|
QLabel* create_title_label(const std::string& title) {
|
||||||
|
auto label = new QLabel(title.c_str());
|
||||||
|
label->setObjectName("titleLabel");
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget* SettingsWidgetFactory::BuildSettingsWidget(
|
QWidget* SettingsWidgetFactory::BuildSettingsWidget(
|
||||||
const std::string& set_name) {
|
const std::string& set_name) {
|
||||||
const auto& sets = settings_.settings();
|
const auto& sets = settings_.settings();
|
||||||
|
@ -53,6 +60,8 @@ QWidget* SettingsWidgetFactory::BuildSettingsWidget(
|
||||||
layout->addWidget(group_box);
|
layout->addWidget(group_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base_widget->setObjectName("settingsContainer");
|
||||||
|
|
||||||
return base_widget;
|
return base_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +90,8 @@ QWidget* SettingsWidgetFactory::CreateWidgetForSettingsItem(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case settings::SettingsType::MultiChoice: {
|
case settings::SettingsType::MultiChoice: {
|
||||||
return nullptr; // TODO:
|
return CreateMultiChoiceWidget(
|
||||||
|
dynamic_cast<settings::IMultiChoiceSettingsItem&>(item));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case settings::SettingsType::Range: {
|
case settings::SettingsType::Range: {
|
||||||
|
@ -109,20 +119,7 @@ QWidget* SettingsWidgetFactory::CreateWidgetForSettingsItem(
|
||||||
|
|
||||||
QWidget* SettingsWidgetFactory::CreateCheckBoxWidget(
|
QWidget* SettingsWidgetFactory::CreateCheckBoxWidget(
|
||||||
settings::BooleanSettingsItem& item) {
|
settings::BooleanSettingsItem& item) {
|
||||||
XCheckBox* checkbox = new XCheckBox();
|
SettingsCheckBox* checkbox = new SettingsCheckBox(item);
|
||||||
checkbox->setText(item.title().c_str());
|
|
||||||
checkbox->setCheckState(*item.cvar()->current_value() ? Qt::Checked
|
|
||||||
: Qt::Unchecked);
|
|
||||||
|
|
||||||
XCheckBox::connect(checkbox, &XCheckBox::stateChanged, [&](int state) {
|
|
||||||
if (state == Qt::Checked) {
|
|
||||||
item.UpdateValue(true);
|
|
||||||
} else if (state == Qt::Unchecked) {
|
|
||||||
item.UpdateValue(false);
|
|
||||||
} else {
|
|
||||||
XELOGW("PartiallyChecked state not supported for SettingsCheckBox");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return CreateWidgetContainer(checkbox);
|
return CreateWidgetContainer(checkbox);
|
||||||
}
|
}
|
||||||
|
@ -133,19 +130,9 @@ QWidget* SettingsWidgetFactory::CreateTextInputWidget(
|
||||||
QVBoxLayout* ctr_layout = new QVBoxLayout();
|
QVBoxLayout* ctr_layout = new QVBoxLayout();
|
||||||
ctr->setLayout(ctr_layout);
|
ctr->setLayout(ctr_layout);
|
||||||
|
|
||||||
QLabel* title_label = new QLabel(item.title().c_str());
|
QLabel* title_label = create_title_label(item.title());
|
||||||
|
|
||||||
XLineEdit* line_edit = new XLineEdit();
|
SettingsLineEdit* line_edit = new SettingsLineEdit(item);
|
||||||
line_edit->setPlaceholderText(item.description().c_str());
|
|
||||||
line_edit->setMaximumWidth(kLineEditMaxWidth);
|
|
||||||
|
|
||||||
const auto& current_text = *item.cvar()->current_value();
|
|
||||||
line_edit->setText(QString(current_text.c_str()));
|
|
||||||
|
|
||||||
XLineEdit::connect(line_edit, &XLineEdit::textChanged,
|
|
||||||
[&](const QString& text) {
|
|
||||||
item.UpdateValue(std::string(text.toUtf8()));
|
|
||||||
});
|
|
||||||
|
|
||||||
ctr_layout->addWidget(title_label);
|
ctr_layout->addWidget(title_label);
|
||||||
ctr_layout->addWidget(line_edit);
|
ctr_layout->addWidget(line_edit);
|
||||||
|
@ -161,32 +148,20 @@ QWidget* SettingsWidgetFactory::CreatePathInputWidget(
|
||||||
ctr_layout->setContentsMargins(0, 0, 0, 0);
|
ctr_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
ctr_layout->setSpacing(8);
|
ctr_layout->setSpacing(8);
|
||||||
|
|
||||||
QLabel* title_label = new QLabel(item.title().c_str());
|
QLabel* title_label = create_title_label(item.title());
|
||||||
|
|
||||||
QHBoxLayout* control_layout = new QHBoxLayout();
|
QHBoxLayout* control_layout = new QHBoxLayout();
|
||||||
control_layout->setSpacing(8);
|
control_layout->setSpacing(8);
|
||||||
|
|
||||||
XLineEdit* line_edit = new XLineEdit();
|
SettingsLineEdit* line_edit = new SettingsLineEdit(item);
|
||||||
line_edit->setPlaceholderText(item.description().c_str());
|
|
||||||
line_edit->setMaximumWidth(kLineEditMaxWidth);
|
|
||||||
|
|
||||||
const auto& current_path = *item.cvar()->current_value();
|
|
||||||
std::string current_path_str = std::string(current_path.u8string());
|
|
||||||
line_edit->setText(QString(current_path_str.c_str()));
|
|
||||||
|
|
||||||
XPushButton* browse_btn = new XPushButton();
|
XPushButton* browse_btn = new XPushButton();
|
||||||
browse_btn->SetIconFromGlyph(0xE838);
|
browse_btn->SetIconFromGlyph(0xE838);
|
||||||
|
// TODO: Setup browse button logic
|
||||||
|
|
||||||
control_layout->addWidget(line_edit);
|
control_layout->addWidget(line_edit);
|
||||||
control_layout->addWidget(browse_btn);
|
control_layout->addWidget(browse_btn);
|
||||||
control_layout->addStretch();
|
control_layout->addStretch();
|
||||||
|
|
||||||
XLineEdit::connect(line_edit, &XLineEdit::textChanged,
|
|
||||||
[&](const QString& text) {
|
|
||||||
auto path = std::string(text.toUtf8());
|
|
||||||
item.UpdateValue(std::filesystem::path(path));
|
|
||||||
});
|
|
||||||
|
|
||||||
ctr_layout->addWidget(title_label);
|
ctr_layout->addWidget(title_label);
|
||||||
ctr_layout->addLayout(control_layout);
|
ctr_layout->addLayout(control_layout);
|
||||||
|
|
||||||
|
@ -201,20 +176,45 @@ QWidget* SettingsWidgetFactory::CreateNumberInputWidget(
|
||||||
|
|
||||||
QWidget* SettingsWidgetFactory::CreateRangeInputWidget(
|
QWidget* SettingsWidgetFactory::CreateRangeInputWidget(
|
||||||
settings::RangeInputSettingsItem& item) {
|
settings::RangeInputSettingsItem& item) {
|
||||||
using xe::app::settings::ValueType;
|
using xe::app::settings::ValueType;
|
||||||
|
|
||||||
QWidget* ctr = new QWidget();
|
QWidget* ctr = new QWidget();
|
||||||
QVBoxLayout* ctr_layout = new QVBoxLayout();
|
QHBoxLayout* ctr_layout = new QHBoxLayout();
|
||||||
|
ctr_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
ctr_layout->setSpacing(20);
|
||||||
ctr->setLayout(ctr_layout);
|
ctr->setLayout(ctr_layout);
|
||||||
|
|
||||||
QLabel* title_label = new QLabel(item.title().c_str());
|
QLabel* title_label = create_title_label(item.title());
|
||||||
|
|
||||||
XSlider* slider = new XSlider();
|
SettingsSlider* slider = new SettingsSlider(item);
|
||||||
int min = xe::app::settings::number_value_to_int(item.min());
|
int min = xe::app::settings::number_value_to_int(item.min());
|
||||||
int max = xe::app::settings::number_value_to_int(item.max());
|
int max = xe::app::settings::number_value_to_int(item.max());
|
||||||
|
|
||||||
|
SettingsSlider::connect(slider, &SettingsSlider::valueChanged,
|
||||||
|
[&](int value) { item.UpdateValue(value); });
|
||||||
|
|
||||||
ctr_layout->addWidget(title_label);
|
ctr_layout->addWidget(title_label);
|
||||||
ctr_layout->addWidget(slider);
|
ctr_layout->addWidget(slider);
|
||||||
|
ctr_layout->addStretch();
|
||||||
|
|
||||||
|
return CreateWidgetContainer(ctr);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* SettingsWidgetFactory::CreateMultiChoiceWidget(
|
||||||
|
settings::IMultiChoiceSettingsItem& item) {
|
||||||
|
QWidget* ctr = new QWidget();
|
||||||
|
QHBoxLayout* ctr_layout = new QHBoxLayout();
|
||||||
|
ctr_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
ctr_layout->setSpacing(20);
|
||||||
|
ctr->setLayout(ctr_layout);
|
||||||
|
|
||||||
|
QLabel* title_label = create_title_label(item.title());
|
||||||
|
|
||||||
|
SettingsComboBox* combobox = new SettingsComboBox(item);
|
||||||
|
|
||||||
|
ctr_layout->addWidget(title_label);
|
||||||
|
ctr_layout->addWidget(combobox);
|
||||||
|
ctr_layout->addStretch();
|
||||||
|
|
||||||
return CreateWidgetContainer(ctr);
|
return CreateWidgetContainer(ctr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SettingsWidgetFactory {
|
||||||
QWidget* CreatePathInputWidget(settings::FilePathInputSettingsItem& item);
|
QWidget* CreatePathInputWidget(settings::FilePathInputSettingsItem& item);
|
||||||
QWidget* CreateNumberInputWidget(settings::NumberInputSettingsItem& item);
|
QWidget* CreateNumberInputWidget(settings::NumberInputSettingsItem& item);
|
||||||
QWidget* CreateRangeInputWidget(settings::RangeInputSettingsItem& item);
|
QWidget* CreateRangeInputWidget(settings::RangeInputSettingsItem& item);
|
||||||
//QWidget* CreateMultiChoiceWidget(settings::MultiChoiceSettingsItem<>& item);
|
QWidget* CreateMultiChoiceWidget(settings::IMultiChoiceSettingsItem& item);
|
||||||
QWidget* CreateActionWidget(settings::ActionSettingsItem& item);
|
QWidget* CreateActionWidget(settings::ActionSettingsItem& item);
|
||||||
|
|
||||||
QWidget* CreateWidgetContainer(QWidget* target);
|
QWidget* CreateWidgetContainer(QWidget* target);
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "settings_checkbox.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
SettingsCheckBox::SettingsCheckBox(BooleanSettingsItem& item)
|
||||||
|
: XCheckBox(item.title().c_str()), item_(item) {
|
||||||
|
assert_true(Initialize(), "Could not initialize SettingsCheckBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsCheckBox::~SettingsCheckBox() { item_.cvar()->RemoveListener(this); }
|
||||||
|
|
||||||
|
bool SettingsCheckBox::Initialize() {
|
||||||
|
item_.cvar()->RegisterListener(this);
|
||||||
|
|
||||||
|
setCheckState(*item_.cvar()->current_value() ? Qt::Checked : Qt::Unchecked);
|
||||||
|
|
||||||
|
// update cvar when checkbox state changes
|
||||||
|
XCheckBox::connect(this, &XCheckBox::stateChanged, [&](int state) {
|
||||||
|
is_value_updating_ = true;
|
||||||
|
if (state == Qt::Checked) {
|
||||||
|
item_.UpdateValue(true);
|
||||||
|
} else if (state == Qt::Unchecked) {
|
||||||
|
item_.UpdateValue(false);
|
||||||
|
} else {
|
||||||
|
XELOGW("PartiallyChecked state not supported for SettingsCheckBox");
|
||||||
|
}
|
||||||
|
is_value_updating_ = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsCheckBox::OnValueUpdated(const ICommandVar& var) {
|
||||||
|
const auto& new_value = item_.cvar()->current_value();
|
||||||
|
if (!this->is_value_updating_) {
|
||||||
|
// emit state change on ui thread
|
||||||
|
QMetaObject::invokeMethod(this, "setChecked", Qt::QueuedConnection,
|
||||||
|
Q_ARG(bool, *new_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_SETTINGS_CHECKBOX_H_
|
||||||
|
#define XENIA_SETTINGS_CHECKBOX_H_
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include "xenia/app/settings/settings.h"
|
||||||
|
#include "xenia/ui/qt/widgets/checkbox.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
class SettingsCheckBox : public XCheckBox, ICommandVarListener {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsCheckBox(BooleanSettingsItem& item);
|
||||||
|
~SettingsCheckBox();
|
||||||
|
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void OnValueUpdated(const ICommandVar& var) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BooleanSettingsItem& item_;
|
||||||
|
std::atomic_bool is_value_updating_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "settings_combobox.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
const int kComboboxMaxWidth = 120;
|
||||||
|
|
||||||
|
SettingsComboBox::SettingsComboBox(IMultiChoiceSettingsItem& item)
|
||||||
|
: XComboBox(), item_(item) {
|
||||||
|
assert_true(Initialize(), "Could not initialize SettingsComboBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsComboBox::~SettingsComboBox() { item_.cvar()->RemoveListener(this); }
|
||||||
|
|
||||||
|
bool SettingsComboBox::Initialize() {
|
||||||
|
setMaximumWidth(kComboboxMaxWidth);
|
||||||
|
|
||||||
|
// load combobox items from setting
|
||||||
|
for (const std::string& option : item_.option_names()) {
|
||||||
|
addItem(option.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default value to match cvar
|
||||||
|
setCurrentIndex(item_.current_index());
|
||||||
|
|
||||||
|
// update cvar when index changes
|
||||||
|
XComboBox::connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||||
|
[&](int index) {
|
||||||
|
is_value_updating_ = true;
|
||||||
|
item_.UpdateIndex(index);
|
||||||
|
is_value_updating_ = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsComboBox::OnValueUpdated(const ICommandVar& var) {
|
||||||
|
if (!is_value_updating_) {
|
||||||
|
int index = item_.current_index();
|
||||||
|
// emit state change on ui thread
|
||||||
|
QMetaObject::invokeMethod(this, "setCurrentIndex", Qt::QueuedConnection,
|
||||||
|
Q_ARG(int, index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_SETTINGS_COMBOBOX_H_
|
||||||
|
#define XENIA_SETTINGS_COMBOBOX_H_
|
||||||
|
|
||||||
|
#include "xenia/app/settings/settings.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/ui/qt/widgets/combobox.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
class SettingsComboBox : public XComboBox, ICommandVarListener {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsComboBox(IMultiChoiceSettingsItem& item);
|
||||||
|
~SettingsComboBox();
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void OnValueUpdated(const ICommandVar& var) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IMultiChoiceSettingsItem& item_;
|
||||||
|
std::atomic_bool is_value_updating_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "settings_line_edit.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
const int kLineEditMaxWidth = 480;
|
||||||
|
|
||||||
|
SettingsLineEdit::SettingsLineEdit(TextInputSettingsItem& item)
|
||||||
|
: XLineEdit(), item_(item), type_(Type::Text) {
|
||||||
|
assert_true(Initialize(), "Could not initialize SettingsLineEdit");
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsLineEdit::SettingsLineEdit(FilePathInputSettingsItem& item)
|
||||||
|
: XLineEdit(), item_(item), type_(Type::Path) {
|
||||||
|
assert_true(Initialize(), "Could not initialize SettingsLineEdit");
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsLineEdit::~SettingsLineEdit() {
|
||||||
|
if (type_ == Type::Path) {
|
||||||
|
auto& item = dynamic_cast<FilePathInputSettingsItem&>(item_);
|
||||||
|
item.cvar()->RemoveListener(this);
|
||||||
|
} else if (type_ == Type::Text) {
|
||||||
|
auto& item = dynamic_cast<TextInputSettingsItem&>(item_);
|
||||||
|
item.cvar()->RemoveListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SettingsLineEdit::Initialize() {
|
||||||
|
if (type_ == Type::Path) {
|
||||||
|
auto item = dynamic_cast<FilePathInputSettingsItem*>(&item_);
|
||||||
|
if (!item) return false;
|
||||||
|
|
||||||
|
this->setPlaceholderText(item->description().c_str());
|
||||||
|
this->setMaximumWidth(kLineEditMaxWidth);
|
||||||
|
|
||||||
|
const auto& current_path = *item->cvar()->current_value();
|
||||||
|
std::string current_path_str = std::string(current_path.u8string());
|
||||||
|
this->setText(QString(current_path_str.c_str()));
|
||||||
|
|
||||||
|
XLineEdit::connect(this, &XLineEdit::textChanged,
|
||||||
|
[=](const QString& text) {
|
||||||
|
auto path = std::string(text.toUtf8());
|
||||||
|
item->UpdateValue(std::filesystem::path(path));
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (type_ == Type::Text) {
|
||||||
|
auto item = dynamic_cast<TextInputSettingsItem*>(&item_);
|
||||||
|
if (!item) return false;
|
||||||
|
|
||||||
|
this->setPlaceholderText(item->description().c_str());
|
||||||
|
this->setMaximumWidth(kLineEditMaxWidth);
|
||||||
|
|
||||||
|
const auto& current_text = *item->cvar()->current_value();
|
||||||
|
this->setText(QString(current_text.c_str()));
|
||||||
|
|
||||||
|
XLineEdit::connect(this, &XLineEdit::textChanged,
|
||||||
|
[=](const QString& text) {
|
||||||
|
item->UpdateValue(std::string(text.toUtf8()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsLineEdit::OnValueUpdated(const ICommandVar& var) {
|
||||||
|
if (!is_value_updating_) {
|
||||||
|
QString text = this->text();
|
||||||
|
if (type_ == Type::Path) {
|
||||||
|
auto& item = dynamic_cast<FilePathInputSettingsItem&>(item_);
|
||||||
|
text = item.cvar()->current_value()->string().c_str();
|
||||||
|
} else if (type_ == Type::Text) {
|
||||||
|
auto& item = dynamic_cast<TextInputSettingsItem&>(item_);
|
||||||
|
text = item.cvar()->current_value()->c_str();
|
||||||
|
}
|
||||||
|
QMetaObject::invokeMethod(this, "setText", Qt::QueuedConnection,
|
||||||
|
Q_ARG(QString, text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_SETTINGS_LINE_EDIT_H_
|
||||||
|
#define XENIA_SETTINGS_LINE_EDIT_H_
|
||||||
|
|
||||||
|
#include "xenia/app/settings/settings.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/ui/qt/widgets/line_edit.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
class SettingsLineEdit : public XLineEdit, ICommandVarListener {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
enum class Type { Text, Path };
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsLineEdit(TextInputSettingsItem& item);
|
||||||
|
explicit SettingsLineEdit(FilePathInputSettingsItem& item);
|
||||||
|
~SettingsLineEdit();
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void OnValueUpdated(const ICommandVar& var) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ISettingsItem& item_;
|
||||||
|
std::atomic_bool is_value_updating_ = false;
|
||||||
|
Type type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "settings_slider.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
SettingsSlider::SettingsSlider(RangeInputSettingsItem& item)
|
||||||
|
: XSlider(), item_(item) {
|
||||||
|
assert_true(Initialize(), "Could not initialize SettingsSlider");
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSlider::~SettingsSlider() { item_.cvar()->RemoveListener(this); }
|
||||||
|
|
||||||
|
bool SettingsSlider::Initialize() {
|
||||||
|
int min = number_value_to_int(item_.min());
|
||||||
|
int max = number_value_to_int(item_.max());
|
||||||
|
|
||||||
|
this->setMinimum(min);
|
||||||
|
this->setMaximum(max);
|
||||||
|
|
||||||
|
int current_value = number_value_to_int(item_.current_value());
|
||||||
|
setValue(current_value);
|
||||||
|
|
||||||
|
XSlider::connect(this, &XSlider::valueChanged, [&](int value) {
|
||||||
|
// TODO: handle UpdateValue returning false for value out of range
|
||||||
|
item_.UpdateValue(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsSlider::OnValueUpdated(const ICommandVar& var) {
|
||||||
|
if (!is_value_updating_) {
|
||||||
|
int current_value = number_value_to_int(item_.current_value());
|
||||||
|
// update value on UI thread
|
||||||
|
QMetaObject::invokeMethod(this, "setValue", Qt::QueuedConnection,
|
||||||
|
Q_ARG(int, current_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2021 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_SETTINGS_SLIDER_H_
|
||||||
|
#define XENIA_SETTINGS_SLIDER_H_
|
||||||
|
|
||||||
|
#include "xenia/app/settings/settings.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/ui/qt/widgets/slider.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
using namespace xe::app::settings;
|
||||||
|
using namespace xe::cvar;
|
||||||
|
|
||||||
|
class SettingsSlider : public XSlider, ICommandVarListener {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsSlider(RangeInputSettingsItem& item);
|
||||||
|
~SettingsSlider();
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void OnValueUpdated(const ICommandVar& var) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RangeInputSettingsItem& item_;
|
||||||
|
std::atomic_bool is_value_updating_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue