Skip to content

Commit

Permalink
ExpressionParser/DolphinQt: Added parse results to UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordan-woyak committed Oct 11, 2019
1 parent c8b2188 commit ca7ce67
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 110 deletions.
112 changes: 70 additions & 42 deletions Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp
Expand Up @@ -4,20 +4,21 @@

#include "DolphinQt/Config/Mapping/IOWindow.h"

#include <optional>
#include <thread>

#include <QComboBox>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QSlider>
#include <QSpinBox>
#include <QSyntaxHighlighter>
#include <QVBoxLayout>

#include "Core/Core.h"
Expand All @@ -35,6 +36,7 @@ constexpr int SLIDER_TICK_COUNT = 100;

namespace
{
// TODO: Make sure these functions return colors that will be visible in the current theme.
QTextCharFormat GetSpecialCharFormat()
{
QTextCharFormat format;
Expand Down Expand Up @@ -85,56 +87,78 @@ QTextCharFormat GetFunctionCharFormat()
format.setForeground(QBrush{Qt::darkCyan});
return format;
}
} // namespace

class SyntaxHighlighter : public QSyntaxHighlighter
ControlExpressionSyntaxHighlighter::ControlExpressionSyntaxHighlighter(QTextDocument* parent,
QLineEdit* result)
: QSyntaxHighlighter(parent), m_result_text(result)
{
public:
SyntaxHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) {}
}

void highlightBlock(const QString& text) final override
{
// TODO: This is going to result in improper highlighting with non-ascii characters:
ciface::ExpressionParser::Lexer lexer(text.toStdString());
void ControlExpressionSyntaxHighlighter::highlightBlock(const QString& text)
{
// TODO: This is going to result in improper highlighting with non-ascii characters:
ciface::ExpressionParser::Lexer lexer(text.toStdString());

std::vector<ciface::ExpressionParser::Token> tokens;
const auto tokenize_status = lexer.Tokenize(tokens);

std::vector<ciface::ExpressionParser::Token> tokens;
lexer.Tokenize(tokens);
using ciface::ExpressionParser::TokenType;

using ciface::ExpressionParser::TokenType;
for (auto& token : tokens)
{
std::optional<QTextCharFormat> char_format;

for (auto& token : tokens)
switch (token.type)
{
switch (token.type)
{
case TokenType::TOK_INVALID:
setFormat(token.string_position, token.string_length, GetInvalidCharFormat());
break;
case TokenType::TOK_LPAREN:
case TokenType::TOK_RPAREN:
case TokenType::TOK_COMMA:
setFormat(token.string_position, token.string_length, GetSpecialCharFormat());
break;
case TokenType::TOK_LITERAL:
setFormat(token.string_position, token.string_length, GetLiteralCharFormat());
break;
case TokenType::TOK_CONTROL:
setFormat(token.string_position, token.string_length, GetControlCharFormat());
break;
case TokenType::TOK_FUNCTION:
setFormat(token.string_position, token.string_length, GetFunctionCharFormat());
break;
case TokenType::TOK_VARIABLE:
setFormat(token.string_position, token.string_length, GetVariableCharFormat());
break;
default:
if (token.IsBinaryOperator())
setFormat(token.string_position, token.string_length, GetOperatorCharFormat());
break;
}
case TokenType::TOK_INVALID:
char_format = GetInvalidCharFormat();
break;
case TokenType::TOK_LPAREN:
case TokenType::TOK_RPAREN:
case TokenType::TOK_COMMA:
char_format = GetSpecialCharFormat();
break;
case TokenType::TOK_LITERAL:
char_format = GetLiteralCharFormat();
break;
case TokenType::TOK_CONTROL:
char_format = GetControlCharFormat();
break;
case TokenType::TOK_FUNCTION:
char_format = GetFunctionCharFormat();
break;
case TokenType::TOK_VARIABLE:
char_format = GetVariableCharFormat();
break;
default:
if (token.IsBinaryOperator())
char_format = GetOperatorCharFormat();
break;
}

if (char_format.has_value())
setFormat(int(token.string_position), int(token.string_length), *char_format);
}
};

} // namespace
if (ciface::ExpressionParser::ParseStatus::Successful != tokenize_status)
{
m_result_text->setText(tr("Invalid Token."));
}
else
{
const auto parse_status = ciface::ExpressionParser::ParseTokens(tokens);

m_result_text->setText(
QString::fromStdString(parse_status.description.value_or(_trans("Success."))));

if (ciface::ExpressionParser::ParseStatus::Successful != parse_status.status)
{
const auto token = *parse_status.token;
setFormat(int(token.string_position), int(token.string_length), GetInvalidCharFormat());
}
}
}

IOWindow::IOWindow(QWidget* parent, ControllerEmu::EmulatedController* controller,
ControlReference* ref, IOWindow::Type type)
Expand Down Expand Up @@ -165,9 +189,12 @@ void IOWindow::CreateMainLayout()
m_range_slider = new QSlider(Qt::Horizontal);
m_range_spinbox = new QSpinBox();

m_parse_text = new QLineEdit();
m_parse_text->setReadOnly(true);

m_expression_text = new QPlainTextEdit();
m_expression_text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
new SyntaxHighlighter(m_expression_text->document());
new ControlExpressionSyntaxHighlighter(m_expression_text->document(), m_parse_text);

m_operators_combo = new QComboBox();
m_operators_combo->addItem(tr("Operators"));
Expand Down Expand Up @@ -234,6 +261,7 @@ void IOWindow::CreateMainLayout()

m_main_layout->addLayout(hbox, 2);
m_main_layout->addWidget(m_expression_text, 1);
m_main_layout->addWidget(m_parse_text);

// Button Box
m_main_layout->addWidget(m_button_box);
Expand Down
16 changes: 16 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/IOWindow.h
Expand Up @@ -6,6 +6,7 @@

#include <QDialog>
#include <QString>
#include <QSyntaxHighlighter>

#include "Common/Flag.h"
#include "InputCommon/ControllerInterface/Device.h"
Expand All @@ -14,6 +15,7 @@ class ControlReference;
class QAbstractButton;
class QComboBox;
class QDialogButtonBox;
class QLineEdit;
class QListWidget;
class QVBoxLayout;
class QWidget;
Expand All @@ -27,6 +29,19 @@ namespace ControllerEmu
class EmulatedController;
}

class ControlExpressionSyntaxHighlighter final : public QSyntaxHighlighter
{
Q_OBJECT
public:
ControlExpressionSyntaxHighlighter(QTextDocument* parent, QLineEdit* result);

protected:
void highlightBlock(const QString& text) final override;

private:
QLineEdit* const m_result_text;
};

class IOWindow final : public QDialog
{
Q_OBJECT
Expand Down Expand Up @@ -81,6 +96,7 @@ class IOWindow final : public QDialog

// Textarea
QPlainTextEdit* m_expression_text;
QLineEdit* m_parse_text;

// Buttonbox
QDialogButtonBox* m_button_box;
Expand Down
Expand Up @@ -54,7 +54,9 @@ std::string ControlReference::GetExpression() const
void ControlReference::SetExpression(std::string expr)
{
m_expression = std::move(expr);
std::tie(m_parse_status, m_parsed_expression) = ParseExpression(m_expression);
auto parse_result = ParseExpression(m_expression);
m_parse_status = parse_result.status;
m_parsed_expression = std::move(parse_result.expr);
}

ControlReference::ControlReference() : range(1), m_parsed_expression(nullptr)
Expand Down

0 comments on commit ca7ce67

Please sign in to comment.