citra-qt: Rewrite register widget
This commit is contained in:
parent
a46371329d
commit
868e6f2d82
8 changed files with 352 additions and 67 deletions
|
@ -13,6 +13,8 @@ set(SRCS
|
||||||
debugger/graphics_framebuffer.cpp
|
debugger/graphics_framebuffer.cpp
|
||||||
debugger/ramview.cpp
|
debugger/ramview.cpp
|
||||||
debugger/registers.cpp
|
debugger/registers.cpp
|
||||||
|
debugger/register_view.cpp
|
||||||
|
debugger/util.cpp
|
||||||
util/spinbox.cpp
|
util/spinbox.cpp
|
||||||
bootmanager.cpp
|
bootmanager.cpp
|
||||||
hotkeys.cpp
|
hotkeys.cpp
|
||||||
|
@ -33,6 +35,8 @@ set(HEADERS
|
||||||
debugger/graphics_framebuffer.h
|
debugger/graphics_framebuffer.h
|
||||||
debugger/ramview.h
|
debugger/ramview.h
|
||||||
debugger/registers.h
|
debugger/registers.h
|
||||||
|
debugger/register_view.h
|
||||||
|
debugger/util.h
|
||||||
util/spinbox.h
|
util/spinbox.h
|
||||||
bootmanager.h
|
bootmanager.h
|
||||||
hotkeys.h
|
hotkeys.h
|
||||||
|
|
168
src/citra_qt/debugger/register_view.cpp
Normal file
168
src/citra_qt/debugger/register_view.cpp
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QShortcut>
|
||||||
|
|
||||||
|
#include "core/debugger/debug_interface.h"
|
||||||
|
|
||||||
|
#include "register_view.h"
|
||||||
|
|
||||||
|
RegisterView::RegisterView(QWidget* parent) : QFrame(parent) {
|
||||||
|
// initialize registers
|
||||||
|
for (int cat = 0; cat < 2; cat++) {
|
||||||
|
for (int index = 0; index < g_debug->GetNumRegsInCategory(cat); index++) {
|
||||||
|
Register reg;
|
||||||
|
reg.category = cat;
|
||||||
|
reg.index = index;
|
||||||
|
reg.oldValue = 0;
|
||||||
|
reg.changed = false;
|
||||||
|
|
||||||
|
registers.append(reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeSize();
|
||||||
|
|
||||||
|
last_pc = 0;
|
||||||
|
selection = 0;
|
||||||
|
|
||||||
|
QShortcut* up_shortcut = new QShortcut(QKeySequence(Qt::Key_Up), this);
|
||||||
|
up_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
connect(up_shortcut, SIGNAL(activated()), this, SLOT(previousRegister()));
|
||||||
|
|
||||||
|
QShortcut* down_shortcut = new QShortcut(QKeySequence(Qt::Key_Down), this);
|
||||||
|
down_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
connect(down_shortcut, SIGNAL(activated()), this, SLOT(nextRegister()));
|
||||||
|
|
||||||
|
setFocusPolicy(Qt::FocusPolicy::ClickFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::initializeSize() {
|
||||||
|
// calculate max register name length
|
||||||
|
int max_length = 0;
|
||||||
|
for (int i = 0; i < registers.size(); i++) {
|
||||||
|
const char* name = g_debug->GetRegName(registers[i].category,registers[i].index);
|
||||||
|
max_length = qMax<int>(max_length, strlen(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize positions
|
||||||
|
border_gap = 3;
|
||||||
|
value_offset = border_gap + (max_length + 1) * font.charWidth();
|
||||||
|
|
||||||
|
// characters per line = length of register name + space + length of register value
|
||||||
|
int numChars = max_length + 1 + 8;
|
||||||
|
|
||||||
|
// calculate size of widget. borderGap pixels to all sides,
|
||||||
|
// and as many rows and columns as needed
|
||||||
|
QSize size = QSize(2 * border_gap + numChars*font.charWidth(),
|
||||||
|
2 * border_gap + registers.size()*font.charHeight());
|
||||||
|
|
||||||
|
// make sure the widget has exactly that size
|
||||||
|
setMinimumSize(size);
|
||||||
|
setMaximumSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::refreshChangedRegs() {
|
||||||
|
// the registers need to be refreshed if the PC of the core has
|
||||||
|
// changed since the last call
|
||||||
|
if (g_debug->GetPC() == last_pc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Register& reg: registers) {
|
||||||
|
unsigned int value = g_debug->GetRegValue(reg.category,reg.index);
|
||||||
|
reg.changed = (value != reg.oldValue);
|
||||||
|
reg.oldValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_pc = g_debug->GetPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::paintEvent(QPaintEvent* event) {
|
||||||
|
QPainter p(this);
|
||||||
|
|
||||||
|
refreshChangedRegs();
|
||||||
|
|
||||||
|
// clear background
|
||||||
|
p.setBrush(QBrush(QColor(Qt::white)));
|
||||||
|
p.setPen(QPen(QColor(Qt::white)));
|
||||||
|
p.drawRect(0, 0, width(), height());
|
||||||
|
|
||||||
|
p.setFont(font.font());
|
||||||
|
|
||||||
|
QPoint pos;
|
||||||
|
QString value;
|
||||||
|
for (int i = 0; i < registers.size(); i++) {
|
||||||
|
Register& reg = registers[i];
|
||||||
|
int y = border_gap + i * font.charHeight();
|
||||||
|
|
||||||
|
// highlight background of selected register
|
||||||
|
if (i == selection)
|
||||||
|
{
|
||||||
|
QColor col(0xE8, 0xEF, 0xFF);
|
||||||
|
p.setBrush(col);
|
||||||
|
p.setPen(col);
|
||||||
|
p.drawRect(0, y - 1, width(), font.charHeight() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw register name
|
||||||
|
pos = font.calculateDrawPos(border_gap, y);
|
||||||
|
p.setPen(QColor(0, 0, 0x60));
|
||||||
|
p.drawText(pos, g_debug->GetRegName(reg.category, reg.index));
|
||||||
|
|
||||||
|
// draw register value
|
||||||
|
pos = font.calculateDrawPos(value_offset, y);
|
||||||
|
value.sprintf("%08X", g_debug->GetRegValue(reg.category, reg.index));
|
||||||
|
|
||||||
|
// draw changed registers in red, rest in black
|
||||||
|
if (reg.changed)
|
||||||
|
p.setPen(QColor(Qt::red));
|
||||||
|
else
|
||||||
|
p.setPen(QColor(Qt::black));
|
||||||
|
|
||||||
|
p.drawText(pos, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw frame last, otherwise it gets overwritten
|
||||||
|
QFrame::paintEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RegisterView::mapPositionToRegister(QPoint pos) const {
|
||||||
|
int y = pos.y();
|
||||||
|
|
||||||
|
if (y < border_gap || y + border_gap >= height())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (y - border_gap) / font.charHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::mousePressEvent(QMouseEvent* event) {
|
||||||
|
int new_selection = mapPositionToRegister(event->pos());
|
||||||
|
if (new_selection != -1 && selection != new_selection) {
|
||||||
|
selection = new_selection;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::mouseMoveEvent(QMouseEvent* event) {
|
||||||
|
if (event->buttons() & (Qt::MouseButton::LeftButton | Qt::MouseButton::RightButton)) {
|
||||||
|
int new_selection = mapPositionToRegister(event->pos());
|
||||||
|
if (new_selection != -1 && selection != new_selection)
|
||||||
|
{
|
||||||
|
selection = new_selection;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::moveSelectionUp() {
|
||||||
|
selection = qMax<int>(0, selection - 1);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterView::moveSelectionDown() {
|
||||||
|
selection = qMin<int>(registers.size() - 1, selection + 1);
|
||||||
|
update();
|
||||||
|
}
|
52
src/citra_qt/debugger/register_view.h
Normal file
52
src/citra_qt/debugger/register_view.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
class RegisterView: public QFrame {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterView(QWidget* parent = NULL);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// Select previous register
|
||||||
|
void moveSelectionUp();
|
||||||
|
|
||||||
|
// Select next register
|
||||||
|
void moveSelectionDown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Reloads register values if necessary
|
||||||
|
void refreshChangedRegs();
|
||||||
|
|
||||||
|
// Calculates and sets the widget size and the used positions
|
||||||
|
void initializeSize();
|
||||||
|
|
||||||
|
// Returns the number of the register at the given position
|
||||||
|
int mapPositionToRegister(QPoint pos) const;
|
||||||
|
|
||||||
|
struct Register
|
||||||
|
{
|
||||||
|
unsigned int oldValue;
|
||||||
|
bool changed;
|
||||||
|
int category;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
DebuggerFont font;
|
||||||
|
int border_gap;
|
||||||
|
int value_offset;
|
||||||
|
|
||||||
|
unsigned int last_pc;
|
||||||
|
QVector<Register> registers;
|
||||||
|
int selection;
|
||||||
|
};
|
|
@ -2,68 +2,53 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "registers.h"
|
#include <QSpacerItem>
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/debugger/debug_interface.h"
|
||||||
#include "core/arm/arm_interface.h"
|
|
||||||
|
#include "registers.h"
|
||||||
|
|
||||||
RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
|
RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
|
||||||
{
|
{
|
||||||
cpu_regs_ui.setupUi(this);
|
cpu_regs_ui.setupUi(this);
|
||||||
|
|
||||||
tree = cpu_regs_ui.treeWidget;
|
for (int i = 0; i < g_debug->GetNumRegsInCategory(REGCAT_CPSR_FLAGS); i++)
|
||||||
tree->addTopLevelItem(registers = new QTreeWidgetItem(QStringList("Registers")));
|
|
||||||
tree->addTopLevelItem(CSPR = new QTreeWidgetItem(QStringList("CSPR")));
|
|
||||||
|
|
||||||
registers->setExpanded(true);
|
|
||||||
CSPR->setExpanded(true);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i)
|
|
||||||
{
|
{
|
||||||
QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0'))));
|
const char* name = g_debug->GetRegName(REGCAT_CPSR_FLAGS,i);
|
||||||
registers->addChild(child);
|
|
||||||
|
QCheckBox* box = new QCheckBox(name,this);
|
||||||
|
cpu_regs_ui.flags->addWidget(box);
|
||||||
|
connect(box,SIGNAL(stateChanged(int)),this,SLOT(OnFlagToggled(int)));
|
||||||
|
|
||||||
|
flagLookup[box] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("M")));
|
cpu_regs_ui.flags->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum,QSizePolicy::Expanding));
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("T")));
|
}
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("F")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("I")));
|
void RegistersWidget::OnFlagToggled(int state)
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("A")));
|
{
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("E")));
|
QCheckBox* sender = dynamic_cast<QCheckBox*>(this->sender());
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("IT")));
|
int index = flagLookup[sender];
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("GE")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("DNM")));
|
g_debug->SetRegValue(REGCAT_CPSR_FLAGS,index,state == 0 ? 0 : 1);
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("J")));
|
cpu_regs_ui.registerView->update();
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("Q")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("V")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("C")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("Z")));
|
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::OnDebugModeEntered()
|
void RegistersWidget::OnDebugModeEntered()
|
||||||
{
|
{
|
||||||
ARM_Interface* app_core = Core::g_app_core;
|
for (auto it = flagLookup.begin(); it != flagLookup.end(); it++)
|
||||||
|
{
|
||||||
|
QCheckBox* box = it.key();
|
||||||
|
int index = it.value();
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i)
|
bool check = g_debug->GetRegValue(REGCAT_CPSR_FLAGS,index) != 0;
|
||||||
registers->child(i)->setText(1, QString("0x%1").arg(app_core->GetReg(i), 8, 16, QLatin1Char('0')));
|
box->blockSignals(true);
|
||||||
|
box->setChecked(check);
|
||||||
|
box->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
CSPR->setText(1, QString("0x%1").arg(app_core->GetCPSR(), 8, 16, QLatin1Char('0')));
|
cpu_regs_ui.registerView->update();
|
||||||
CSPR->child(0)->setText(1, QString("b%1").arg(app_core->GetCPSR() & 0x1F, 5, 2, QLatin1Char('0'))); // M - Mode
|
|
||||||
CSPR->child(1)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 5) & 0x1)); // T - State
|
|
||||||
CSPR->child(2)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 6) & 0x1)); // F - FIQ disable
|
|
||||||
CSPR->child(3)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 7) & 0x1)); // I - IRQ disable
|
|
||||||
CSPR->child(4)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 8) & 0x1)); // A - Imprecise abort
|
|
||||||
CSPR->child(5)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 9) & 0x1)); // E - Data endianess
|
|
||||||
CSPR->child(6)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 10) & 0x3F)); // IT - If-Then state (DNM)
|
|
||||||
CSPR->child(7)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 16) & 0xF)); // GE - Greater-than-or-Equal
|
|
||||||
CSPR->child(8)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 20) & 0xF)); // DNM - Do not modify
|
|
||||||
CSPR->child(9)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 24) & 0x1)); // J - Java state
|
|
||||||
CSPR->child(10)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 27) & 0x1)); // Q - Sticky overflow
|
|
||||||
CSPR->child(11)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 28) & 0x1)); // V - Overflow
|
|
||||||
CSPR->child(12)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 29) & 0x1)); // C - Carry/Borrow/Extend
|
|
||||||
CSPR->child(13)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 30) & 0x1)); // Z - Zero
|
|
||||||
CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::OnDebugModeLeft()
|
void RegistersWidget::OnDebugModeLeft()
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
|
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
class QTreeWidget;
|
class QTreeWidget;
|
||||||
|
|
||||||
|
|
||||||
class RegistersWidget : public QDockWidget
|
class RegistersWidget : public QDockWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -19,12 +22,9 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void OnDebugModeEntered();
|
void OnDebugModeEntered();
|
||||||
void OnDebugModeLeft();
|
void OnDebugModeLeft();
|
||||||
|
void OnFlagToggled(int state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QMap<QCheckBox*,int> flagLookup;
|
||||||
Ui::ARMRegisters cpu_regs_ui;
|
Ui::ARMRegisters cpu_regs_ui;
|
||||||
|
|
||||||
QTreeWidget* tree;
|
|
||||||
|
|
||||||
QTreeWidgetItem* registers;
|
|
||||||
QTreeWidgetItem* CSPR;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,27 +14,41 @@
|
||||||
<string>ARM Registers</string>
|
<string>ARM Registers</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QTreeWidget" name="treeWidget">
|
<widget class="RegisterView" name="registerView">
|
||||||
<property name="alternatingRowColors">
|
<property name="frameShape">
|
||||||
<bool>true</bool>
|
<enum>QFrame::Panel</enum>
|
||||||
</property>
|
</property>
|
||||||
<column>
|
<property name="frameShadow">
|
||||||
<property name="text">
|
<enum>QFrame::Sunken</enum>
|
||||||
<string>Register</string>
|
|
||||||
</property>
|
</property>
|
||||||
</column>
|
<property name="lineWidth">
|
||||||
<column>
|
<number>1</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Value</string>
|
<property name="midLineWidth">
|
||||||
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="flags">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>RegisterView</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>debugger/register_view.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
29
src/citra_qt/debugger/util.cpp
Normal file
29
src/citra_qt/debugger/util.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QFontMetrics>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
DebuggerFont::DebuggerFont() {
|
||||||
|
font_ = QFont("Lucida Console", 10);
|
||||||
|
font_.setStyleHint(QFont::Courier, QFont::PreferMatch);
|
||||||
|
updateMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerFont::setBold(bool bold) {
|
||||||
|
font_.setBold(bold);
|
||||||
|
updateMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint DebuggerFont::calculateDrawPos(int left, int top) {
|
||||||
|
return QPoint(left, top + charHeight() - charDescent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerFont::updateMetrics() {
|
||||||
|
QFontMetrics metrics = QFontMetrics(font_);
|
||||||
|
width = metrics.width('0');
|
||||||
|
height = metrics.height();
|
||||||
|
descent = metrics.descent();
|
||||||
|
}
|
33
src/citra_qt/debugger/util.h
Normal file
33
src/citra_qt/debugger/util.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFont>
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
// Abstracts font calculations used by some
|
||||||
|
// debugger widgets
|
||||||
|
class DebuggerFont {
|
||||||
|
public:
|
||||||
|
DebuggerFont();
|
||||||
|
|
||||||
|
// Returns the position needed to draw a string that should
|
||||||
|
// have its upper left corner at the given coordinates
|
||||||
|
QPoint calculateDrawPos(int left, int top);
|
||||||
|
|
||||||
|
QFont& font() { return font_; }
|
||||||
|
int charWidth() const { return width; };
|
||||||
|
int charHeight() const { return height; };
|
||||||
|
int charDescent() const { return descent; };
|
||||||
|
|
||||||
|
void setBold(bool bold);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateMetrics();
|
||||||
|
|
||||||
|
QFont font_;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int descent;
|
||||||
|
};
|
Loading…
Reference in a new issue