235 lines
7.0 KiB
C++
235 lines
7.0 KiB
C++
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
|
|
#include <QComboBox>
|
|
#include <QPushButton>
|
|
|
|
#include <utility>
|
|
|
|
namespace {
|
|
|
|
QPushButton* AsButton(QObject* object) {
|
|
return qobject_cast<QPushButton*>(object);
|
|
}
|
|
|
|
}
|
|
|
|
MainWindow::MainWindow(QWidget* parent)
|
|
: QMainWindow(parent), ui(new Ui::MainWindow) {
|
|
ui->setupUi(this);
|
|
|
|
// Все кнопки с цифрами
|
|
const QList<QPushButton*> digit_buttons = {
|
|
ui->tb_zero, ui->tb_one, ui->tb_two, ui->tb_three, ui->tb_four,
|
|
ui->tb_five, ui->tb_six, ui->tb_seven, ui->tb_eight, ui->tb_nine
|
|
};
|
|
for (QPushButton* button : digit_buttons) {
|
|
connect(button, &QPushButton::clicked, this, &MainWindow::OnDigitClicked);
|
|
}
|
|
|
|
// Арифметичсекие операции
|
|
const QList<QPushButton*> operation_buttons = {
|
|
ui->tb_add, ui->tb_substract, ui->tb_multiplicate, ui->tb_divide, ui->tb_power
|
|
};
|
|
for (QPushButton* button : operation_buttons) {
|
|
connect(button, &QPushButton::clicked, this, &MainWindow::OnOperationClicked);
|
|
}
|
|
|
|
// Управляющие кнопки: равно, память, знак, стирание символа и точки
|
|
const QList<QPushButton*> control_buttons = {
|
|
ui->tb_equal, ui->tb_reset, ui->tb_ms, ui->tn_mr, ui->tb_mc,
|
|
ui->tb_negate, ui->tb_backspace, ui->tb_extra
|
|
};
|
|
for (QPushButton* button : control_buttons) {
|
|
connect(button, &QPushButton::clicked, this, &MainWindow::OnControlClicked);
|
|
}
|
|
|
|
// Выпадающие кнопки с выбором типа числа
|
|
connect(ui->cmb_controller,
|
|
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
this,
|
|
&MainWindow::OnControllerChanged);
|
|
|
|
// Дефолтные значения при запуске
|
|
SetInputText("0");
|
|
SetFormulaText("");
|
|
SetMemText("");
|
|
}
|
|
|
|
MainWindow::~MainWindow() {
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::SetInputText(const std::string& text) {
|
|
// Показываем обычный результат вычислений
|
|
ui->l_result->setStyleSheet("");
|
|
ui->l_result->setText(QString::fromStdString(text));
|
|
}
|
|
|
|
void MainWindow::SetErrorText(const std::string& text) {
|
|
// Ошибки выводим в том же поле, но красным цветом
|
|
ui->l_result->setStyleSheet("color: red;");
|
|
ui->l_result->setText(QString::fromStdString(text));
|
|
}
|
|
|
|
void MainWindow::SetFormulaText(const std::string& text) {
|
|
// Отображение текущей формулы
|
|
ui->l_formula->setText(QString::fromStdString(text));
|
|
}
|
|
|
|
void MainWindow::SetMemText(const std::string& text) {
|
|
// Отображение значения в памяти
|
|
ui->l_memory->setText(QString::fromStdString(text));
|
|
}
|
|
|
|
void MainWindow::SetExtraKey(const std::optional<std::string>& key) {
|
|
// В некоторых режимах точка не используется
|
|
if (!key) {
|
|
ui->tb_extra->hide();
|
|
return;
|
|
}
|
|
// Если точка используется
|
|
ui->tb_extra->setText(QString::fromStdString(*key));
|
|
ui->tb_extra->show();
|
|
}
|
|
|
|
void MainWindow::SetDigitKeyCallback(std::function<void(int key)> cb) {
|
|
digit_cb_ = std::move(cb);
|
|
}
|
|
|
|
void MainWindow::SetProcessOperationKeyCallback(std::function<void(Operation key)> cb) {
|
|
operation_cb_ = std::move(cb);
|
|
}
|
|
|
|
void MainWindow::SetProcessControlKeyCallback(std::function<void(ControlKey key)> cb) {
|
|
control_cb_ = std::move(cb);
|
|
}
|
|
|
|
void MainWindow::SetControllerCallback(std::function<void(ControllerType controller)> cb) {
|
|
controller_cb_ = std::move(cb);
|
|
}
|
|
|
|
void MainWindow::OnDigitClicked() {
|
|
// Игнорируем если контролер еще не подклчил обработчик
|
|
const QPushButton* button = AsButton(sender());
|
|
if (!button || !digit_cb_) {
|
|
return;
|
|
}
|
|
|
|
// Передаем нажатую цифру в контролер
|
|
digit_cb_(button->text().toInt());
|
|
}
|
|
|
|
void MainWindow::OnOperationClicked() {
|
|
// Определяем нажатую кнопку с цифрой
|
|
const QPushButton* button = AsButton(sender());
|
|
if (!button || !operation_cb_) {
|
|
return;
|
|
}
|
|
|
|
const auto operation = OperationFromObjectName(button->objectName());
|
|
if (operation) {
|
|
operation_cb_(*operation);
|
|
}
|
|
}
|
|
|
|
void MainWindow::OnControlClicked() {
|
|
// Определяем нажатую кнопку управляющих кнопок
|
|
const QPushButton* button = AsButton(sender());
|
|
if (!button || !control_cb_) {
|
|
return;
|
|
}
|
|
|
|
const auto key = ControlFromObjectName(button->objectName());
|
|
if (key) {
|
|
control_cb_(*key);
|
|
}
|
|
}
|
|
|
|
void MainWindow::OnControllerChanged() {
|
|
// Смена режима работы
|
|
if (!controller_cb_) {
|
|
return;
|
|
}
|
|
|
|
const auto controller = ControllerFromText(ui->cmb_controller->currentText());
|
|
if (controller) {
|
|
controller_cb_(*controller);
|
|
}
|
|
}
|
|
|
|
std::optional<Operation> MainWindow::OperationFromObjectName(const QString& object_name) {
|
|
// Определяем какая арифметичская кнопка была нажата
|
|
if (object_name == "tb_add") {
|
|
return Operation::ADDITION;
|
|
}
|
|
if (object_name == "tb_substract") {
|
|
return Operation::SUBTRACTION;
|
|
}
|
|
if (object_name == "tb_multiplicate") {
|
|
return Operation::MULTIPLICATION;
|
|
}
|
|
if (object_name == "tb_divide") {
|
|
return Operation::DIVISION;
|
|
}
|
|
if (object_name == "tb_power") {
|
|
return Operation::POWER;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::optional<ControlKey> MainWindow::ControlFromObjectName(const QString& object_name) {
|
|
// Определяем какая управляющая кнопка была нажата
|
|
if (object_name == "tb_equal") {
|
|
return ControlKey::EQUALS;
|
|
}
|
|
if (object_name == "tb_reset") {
|
|
return ControlKey::CLEAR;
|
|
}
|
|
if (object_name == "tb_ms") {
|
|
return ControlKey::MEM_SAVE;
|
|
}
|
|
if (object_name == "tn_mr") {
|
|
return ControlKey::MEM_LOAD;
|
|
}
|
|
if (object_name == "tb_mc") {
|
|
return ControlKey::MEM_CLEAR;
|
|
}
|
|
if (object_name == "tb_negate") {
|
|
return ControlKey::PLUS_MINUS;
|
|
}
|
|
if (object_name == "tb_backspace") {
|
|
return ControlKey::BACKSPACE;
|
|
}
|
|
if (object_name == "tb_extra") {
|
|
return ControlKey::EXTRA_KEY;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::optional<ControllerType> MainWindow::ControllerFromText(const QString& text) {
|
|
// Определяем выбранный тип
|
|
if (text == "double") {
|
|
return ControllerType::DOUBLE;
|
|
}
|
|
if (text == "float") {
|
|
return ControllerType::FLOAT;
|
|
}
|
|
if (text == "uint8_t") {
|
|
return ControllerType::UINT8_T;
|
|
}
|
|
if (text == "int") {
|
|
return ControllerType::INT;
|
|
}
|
|
if (text == "int64_t") {
|
|
return ControllerType::INT64_T;
|
|
}
|
|
if (text == "size_t") {
|
|
return ControllerType::SIZE_T;
|
|
}
|
|
if (text == "Rational") {
|
|
return ControllerType::RATIONAL;
|
|
}
|
|
return std::nullopt;
|
|
}
|