mirror of
https://github.com/libretro/mgba.git
synced 2024-11-23 16:10:01 +00:00
Qt: Add keyboard remapper
This commit is contained in:
parent
0efe988161
commit
81e65c08d8
BIN
res/keymap.png
Normal file
BIN
res/keymap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
136
res/keymap.svg
Normal file
136
res/keymap.svg
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="480px" height="480px" viewBox="0 0 480 480" enable-background="new 0 0 480 480" xml:space="preserve">
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="239.9995" y1="0" x2="239.9995" y2="480.0005">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M480,450c0,16.5684-13.4316,30-30,30H30c-16.5684,0-30-13.4316-30-30V30C0,13.4316,13.4316,0,30,0
|
||||
h420c16.5684,0,30,13.4316,30,30V450z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="239.9995" y1="-479" x2="239.9994" y2="1159.0004">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_2_)" d="M30,473c-12.6821,0-23-10.3174-23-23V30C7,17.3179,17.3179,7,30,7h420c12.6826,0,23,10.3179,23,23
|
||||
v420c0,12.6826-10.3174,23-23,23H30z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="118.3335" y1="291.667" x2="118.3335" y2="47.9991">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_3_)" d="M118.3335,122.333c-46.7603,0-84.667,37.9067-84.667,84.667c0,46.7607,37.9067,84.667,84.667,84.667
|
||||
s84.667-37.9062,84.667-84.667C203.0005,160.2397,165.0938,122.333,118.3335,122.333z M118.334,278.7344
|
||||
c-39.6172,0-71.7339-32.1172-71.7339-71.7344c0-39.6177,32.1167-71.7339,71.7339-71.7339S190.0679,167.3823,190.0679,207
|
||||
C190.0679,246.6172,157.9512,278.7344,118.334,278.7344z"/>
|
||||
<g>
|
||||
|
||||
<radialGradient id="SVGID_4_" cx="118.8335" cy="138.167" r="103.2725" fx="165.1467" fy="138.167" gradientTransform="matrix(-4.371139e-08 1 -1.42 -6.206884e-08 315.0264 19.3335)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#9C9CB3"/>
|
||||
<stop offset="1" style="stop-color:#333045"/>
|
||||
</radialGradient>
|
||||
<path fill="url(#SVGID_4_)" d="M172.1973,207c0-9.667-3.0029-17.333-3.0029-17.333H135.667v-33.5283
|
||||
c0,0-7.667-3.0029-17.3335-3.0029s-17.333,3.0029-17.333,3.0029v33.5283H67.4727c0,0-3.0029,7.666-3.0029,17.333
|
||||
c0,9.666,3.0029,17.333,3.0029,17.333h33.5278v33.5273c0,0,7.6665,3.0039,17.333,3.0039s17.3335-3.0039,17.3335-3.0039V224.333
|
||||
h33.5273C169.1943,224.333,172.1973,216.666,172.1973,207z"/>
|
||||
<path fill="#5C567D" d="M118.3335,258.8643c-6.9185,0-12.833-1.625-15.333-2.4287V222.333h-34.103
|
||||
c-0.8027-2.5-2.4277-8.4146-2.4277-15.333s1.6245-12.833,2.4277-15.333h34.103v-34.1035c2.5-0.8027,8.4146-2.4277,15.333-2.4277
|
||||
c6.9453,0,12.8408,1.6226,15.3335,2.4258v34.1055h34.1025c0.8032,2.5,2.4277,8.4146,2.4277,15.333
|
||||
c0,6.9448-1.6226,12.8403-2.4258,15.333H133.667v34.1025C131.167,257.2393,125.252,258.8643,118.3335,258.8643z"/>
|
||||
<radialGradient id="SVGID_5_" cx="118.333" cy="220.397" r="69.7522" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#706F8A"/>
|
||||
<stop offset="0.9951" style="stop-color:#2D2842"/>
|
||||
</radialGradient>
|
||||
<circle fill="url(#SVGID_5_)" cx="118.333" cy="207" r="21.2749"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="198.9673" y1="490" x2="198.9673" y2="384.981">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_6_)" d="M198.9678,387.0303c-18.8418,0-34.1162,15.2734-34.1162,34.1162
|
||||
c0,18.8418,15.2744,34.1152,34.1162,34.1152c18.8408,0,34.1152-15.2734,34.1152-34.1152
|
||||
C233.083,402.3037,217.8086,387.0303,198.9678,387.0303z M198.9678,445.7871c-13.6089,0-24.6401-11.0332-24.6401-24.6406
|
||||
c0-13.6094,11.0312-24.6406,24.6401-24.6406c13.6074,0,24.6396,11.0312,24.6396,24.6406
|
||||
C223.6074,434.7539,212.5752,445.7871,198.9678,445.7871z"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="198.9673" y1="437.4414" x2="198.9673" y2="404.8516">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<circle fill="url(#SVGID_7_)" cx="198.9673" cy="421.1465" r="16.2949"/>
|
||||
<circle fill="#5C567D" cx="198.9673" cy="421.1465" r="15.0737"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="281.0312" y1="490" x2="281.0312" y2="384.981">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_8_)" d="M281.0322,387.0303c-18.8418,0-34.1162,15.2734-34.1162,34.1162
|
||||
c0,18.8418,15.2744,34.1152,34.1162,34.1152c18.8408,0,34.1152-15.2734,34.1152-34.1152
|
||||
C315.1475,402.3037,299.873,387.0303,281.0322,387.0303z M281.0322,445.7871c-13.6084,0-24.6396-11.0332-24.6396-24.6406
|
||||
c0-13.6094,11.0312-24.6406,24.6396-24.6406c13.6074,0,24.6396,11.0312,24.6396,24.6406
|
||||
C305.6719,434.7539,294.6396,445.7871,281.0322,445.7871z"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="281.0322" y1="437.4414" x2="281.0322" y2="404.8516">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<circle fill="url(#SVGID_9_)" cx="281.0322" cy="421.1465" r="16.2949"/>
|
||||
<circle fill="#5C567D" cx="281.0317" cy="421.1465" r="15.0737"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="356.1787" y1="280.2178" x2="356.1787" y2="134.9952">
|
||||
<stop offset="0" style="stop-color:#7A65F5"/>
|
||||
<stop offset="1" style="stop-color:#302575"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_10_)" d="M437.9521,179.5503c-7.0088-23.9434-32.0986-37.6724-56.043-30.6646l-76.8369,22.4912
|
||||
c-23.9453,7.0073-37.6748,32.0991-30.666,56.043c7.0088,23.9443,32.0996,37.6719,56.0449,30.6621l76.8369-22.4902
|
||||
C431.2314,228.585,444.96,203.4946,437.9521,179.5503z M426.3311,209.6025c-4.6377,8.4756-12.2979,14.6382-21.5703,17.3516
|
||||
l-76.8379,22.4902c-3.3301,0.9746-6.7559,1.4688-10.1816,1.4688c-0.001,0-0.001,0-0.002,0
|
||||
c-15.9443-0.001-30.2109-10.7012-34.6953-26.0215c-2.7148-9.2729-1.6553-19.0479,2.9824-27.5244
|
||||
c4.6387-8.4761,12.2998-14.6387,21.5732-17.3525l76.8379-22.4912c3.3281-0.9741,6.7539-1.4683,10.1807-1.4683
|
||||
c15.9434,0,30.2109,10.7012,34.6963,26.0234C432.0283,191.3516,430.9688,201.1265,426.3311,209.6025z"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="395.9062" y1="217.8188" x2="395.9062" y2="166.6519">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<circle fill="url(#SVGID_11_)" cx="395.9062" cy="192.2358" r="25.584"/>
|
||||
<circle fill="#5C567D" cx="395.9072" cy="192.2358" r="23.666"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="318.9785" y1="239.6406" x2="318.9785" y2="188.4722">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<circle fill="url(#SVGID_12_)" cx="318.979" cy="214.0571" r="25.5835"/>
|
||||
<circle fill="#5C567D" cx="318.98" cy="214.0571" r="23.6665"/>
|
||||
</g>
|
||||
<g>
|
||||
<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="-15.0425" y1="77.9346" x2="55.6245" y2="-5.3989">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_13_)" d="M33.6665,0H61.5c2.9697,1.0112,2.3306,7,2.3306,7l0.0581,8.4844
|
||||
C63.8887,31.3535,48.9922,50,27.9922,50H7.0068c0,0-5.2197,2.312-7.0068-8.0029V30C0,11.5,12.333,0,33.6665,0z"/>
|
||||
<path fill="#5C567D" d="M9.7783,49.1743c-0.2793-0.251-1.166-1.2764-1.7744-4.5308V33.0029c0-16.5234,10.813-26,29.6665-26h26.0854
|
||||
c0.1318,0.709,0.1821,1.7549,0.0996,2.5908L63.835,9.8032l0.0576,8.7114c0,14.3774-13.6406,30.4883-31.8965,30.4883H10.1646
|
||||
L9.7783,49.1743z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="401.0615" y1="77.9336" x2="471.7285" y2="-5.3999" gradientTransform="matrix(-1 0 0 1 896.1055 0)">
|
||||
<stop offset="0" style="stop-color:#333045"/>
|
||||
<stop offset="1" style="stop-color:#9C9CB3"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_14_)" d="M446.334,0h-27.833c-2.9697,1.0112-2.3311,7-2.3311,7l-0.0576,8.4844
|
||||
C416.1123,31.3535,431.0088,50,452.0088,50h20.9854c0,0,5.2197,2.312,7.0068-8.0029V30C480.001,11.5,467.668,0,446.334,0z"/>
|
||||
<path fill="#5C567D" d="M470.2227,49.1743c0.2793-0.251,1.166-1.2764,1.7744-4.5308V33.0029c0-16.5234-10.8135-26-29.667-26
|
||||
h-26.085c-0.1318,0.709-0.1826,1.7549-0.0996,2.5908l0.0205,0.2095l-0.0576,8.7114c0,14.3774,13.6406,30.4883,31.8965,30.4883
|
||||
h21.8311L470.2227,49.1743z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
@ -109,6 +109,27 @@ void GBAInputBindKey(struct GBAInputMap* map, uint32_t type, int key, enum GBAKe
|
||||
impl->map[input] = key;
|
||||
}
|
||||
|
||||
int GBAInputQueryBinding(const struct GBAInputMap* map, uint32_t type, enum GBAKey input) {
|
||||
if (input >= GBA_KEY_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t m;
|
||||
const struct GBAInputMapImpl* impl = 0;
|
||||
for (m = 0; m < map->numMaps; ++m) {
|
||||
if (map->maps[m].type == type) {
|
||||
impl = &map->maps[m];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!impl || !impl->map) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return impl->map[input];
|
||||
}
|
||||
|
||||
|
||||
void GBAInputMapLoad(struct GBAInputMap* map, uint32_t type, const struct Configuration* config) {
|
||||
_loadKey(map, type, config, GBA_KEY_A, "A");
|
||||
_loadKey(map, type, config, GBA_KEY_B, "B");
|
||||
|
@ -15,6 +15,7 @@ void GBAInputMapDeinit(struct GBAInputMap*);
|
||||
|
||||
enum GBAKey GBAInputMapKey(const struct GBAInputMap*, uint32_t type, int key);
|
||||
void GBAInputBindKey(struct GBAInputMap*, uint32_t type, int key, enum GBAKey input);
|
||||
int GBAInputQueryBinding(const struct GBAInputMap*, uint32_t type, enum GBAKey input);
|
||||
|
||||
void GBAInputMapLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*);
|
||||
|
||||
|
@ -34,8 +34,10 @@ set(SOURCE_FILES
|
||||
ConfigController.cpp
|
||||
Display.cpp
|
||||
GBAApp.cpp
|
||||
GBAKeyEditor.cpp
|
||||
GameController.cpp
|
||||
InputController.cpp
|
||||
KeyEditor.cpp
|
||||
LoadSaveState.cpp
|
||||
LogView.cpp
|
||||
SavestateButton.cpp
|
||||
|
171
src/platform/qt/GBAKeyEditor.cpp
Normal file
171
src/platform/qt/GBAKeyEditor.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include "GBAKeyEditor.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QPicture>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "InputController.h"
|
||||
#include "KeyEditor.h"
|
||||
|
||||
extern "C" {
|
||||
#include "gba-input.h"
|
||||
}
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
const qreal GBAKeyEditor::DPAD_CENTER_X = 0.247;
|
||||
const qreal GBAKeyEditor::DPAD_CENTER_Y = 0.431;
|
||||
const qreal GBAKeyEditor::DPAD_WIDTH = 0.1;
|
||||
const qreal GBAKeyEditor::DPAD_HEIGHT = 0.1;
|
||||
|
||||
GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_background(QString(":/res/keymap.png"))
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
|
||||
setMinimumSize(300, 300);
|
||||
|
||||
const GBAInputMap* map = controller->map();
|
||||
|
||||
m_keyDU = new KeyEditor(this);
|
||||
m_keyDD = new KeyEditor(this);
|
||||
m_keyDL = new KeyEditor(this);
|
||||
m_keyDR = new KeyEditor(this);
|
||||
m_keySelect = new KeyEditor(this);
|
||||
m_keyStart = new KeyEditor(this);
|
||||
m_keyA = new KeyEditor(this);
|
||||
m_keyB = new KeyEditor(this);
|
||||
m_keyL = new KeyEditor(this);
|
||||
m_keyR = new KeyEditor(this);
|
||||
m_keyDU->setValue(GBAInputQueryBinding(map, type, GBA_KEY_UP));
|
||||
m_keyDD->setValue(GBAInputQueryBinding(map, type, GBA_KEY_DOWN));
|
||||
m_keyDL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_LEFT));
|
||||
m_keyDR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_RIGHT));
|
||||
m_keySelect->setValue(GBAInputQueryBinding(map, type, GBA_KEY_SELECT));
|
||||
m_keyStart->setValue(GBAInputQueryBinding(map, type, GBA_KEY_START));
|
||||
m_keyA->setValue(GBAInputQueryBinding(map, type, GBA_KEY_A));
|
||||
m_keyB->setValue(GBAInputQueryBinding(map, type, GBA_KEY_B));
|
||||
m_keyL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_L));
|
||||
m_keyR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_R));
|
||||
|
||||
connect(m_keyDU, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_UP);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyDD, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_DOWN);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyDL, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_LEFT);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyDR, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_RIGHT);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keySelect, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_SELECT);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyStart, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_START);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyA, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_A);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyB, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_B);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyL, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_L);
|
||||
setNext();
|
||||
});
|
||||
|
||||
connect(m_keyR, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
||||
controller->bindKey(type, key, GBA_KEY_R);
|
||||
setNext();
|
||||
});
|
||||
|
||||
m_setAll = new QPushButton(tr("Set all"), this);
|
||||
connect(m_setAll, SIGNAL(pressed()), this, SLOT(setAll()));
|
||||
|
||||
m_keyOrder = QList<KeyEditor*>{
|
||||
m_keyDU,
|
||||
m_keyDR,
|
||||
m_keyDD,
|
||||
m_keyDL,
|
||||
m_keyA,
|
||||
m_keyB,
|
||||
m_keySelect,
|
||||
m_keyStart,
|
||||
m_keyL,
|
||||
m_keyR
|
||||
};
|
||||
|
||||
m_currentKey = m_keyOrder.end();
|
||||
|
||||
QPixmap background(":/res/keymap.png");
|
||||
m_background = background.scaled(QSize(300, 300) * devicePixelRatio(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
m_background.setDevicePixelRatio(devicePixelRatio());
|
||||
}
|
||||
|
||||
void GBAKeyEditor::setAll() {
|
||||
m_currentKey = m_keyOrder.begin();
|
||||
(*m_currentKey)->setFocus();
|
||||
}
|
||||
|
||||
void GBAKeyEditor::resizeEvent(QResizeEvent* event) {
|
||||
setLocation(m_setAll, 0.5, 0.2);
|
||||
setLocation(m_keyDU, DPAD_CENTER_X, DPAD_CENTER_Y - DPAD_HEIGHT);
|
||||
setLocation(m_keyDD, DPAD_CENTER_X, DPAD_CENTER_Y + DPAD_HEIGHT);
|
||||
setLocation(m_keyDL, DPAD_CENTER_X - DPAD_WIDTH, DPAD_CENTER_Y);
|
||||
setLocation(m_keyDR, DPAD_CENTER_X + DPAD_WIDTH, DPAD_CENTER_Y);
|
||||
setLocation(m_keySelect, 0.415, 0.93);
|
||||
setLocation(m_keyStart, 0.585, 0.93);
|
||||
setLocation(m_keyA, 0.826, 0.451);
|
||||
setLocation(m_keyB, 0.667, 0.490);
|
||||
setLocation(m_keyL, 0.1, 0.1);
|
||||
setLocation(m_keyR, 0.9, 0.1);
|
||||
}
|
||||
|
||||
void GBAKeyEditor::paintEvent(QPaintEvent* event) {
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(0, 0, m_background);
|
||||
}
|
||||
|
||||
void GBAKeyEditor::setNext() {
|
||||
if (m_currentKey == m_keyOrder.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(*m_currentKey)->hasFocus()) {
|
||||
m_currentKey = m_keyOrder.end();
|
||||
}
|
||||
|
||||
++m_currentKey;
|
||||
if (m_currentKey != m_keyOrder.end()) {
|
||||
(*m_currentKey)->setFocus();
|
||||
} else {
|
||||
(*(m_currentKey - 1))->clearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void GBAKeyEditor::setLocation(QWidget* widget, qreal x, qreal y) {
|
||||
QSize s = size();
|
||||
QSize hint = widget->sizeHint();
|
||||
widget->setGeometry(s.width() * x - hint.width() / 2.0, s.height() * y - hint.height() / 2.0, hint.width(), hint.height());
|
||||
}
|
59
src/platform/qt/GBAKeyEditor.h
Normal file
59
src/platform/qt/GBAKeyEditor.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef QGBA_GBA_KEY_EDITOR
|
||||
#define QGBA_GBA_KEY_EDITOR
|
||||
|
||||
#include <QList>
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
|
||||
class QPushButton;
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class InputController;
|
||||
class KeyEditor;
|
||||
|
||||
class GBAKeyEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GBAKeyEditor(InputController* controller, int type, QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setAll();
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent*) override;
|
||||
virtual void paintEvent(QPaintEvent*) override;
|
||||
|
||||
private:
|
||||
static const qreal DPAD_CENTER_X;
|
||||
static const qreal DPAD_CENTER_Y;
|
||||
static const qreal DPAD_WIDTH;
|
||||
static const qreal DPAD_HEIGHT;
|
||||
|
||||
void setNext();
|
||||
|
||||
void setLocation(QWidget* widget, qreal x, qreal y);
|
||||
|
||||
QPushButton* m_setAll;
|
||||
KeyEditor* m_keyDU;
|
||||
KeyEditor* m_keyDD;
|
||||
KeyEditor* m_keyDL;
|
||||
KeyEditor* m_keyDR;
|
||||
KeyEditor* m_keySelect;
|
||||
KeyEditor* m_keyStart;
|
||||
KeyEditor* m_keyA;
|
||||
KeyEditor* m_keyB;
|
||||
KeyEditor* m_keyL;
|
||||
KeyEditor* m_keyR;
|
||||
QList<KeyEditor*> m_keyOrder;
|
||||
QList<KeyEditor*>::iterator m_currentKey;
|
||||
|
||||
InputController* m_controller;
|
||||
|
||||
QPixmap m_background;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -52,6 +52,10 @@ GBAKey InputController::mapKeyboard(int key) const {
|
||||
return GBAInputMapKey(&m_inputMap, KEYBOARD, key);
|
||||
}
|
||||
|
||||
void InputController::bindKey(uint32_t type, int key, GBAKey gbaKey) {
|
||||
return GBAInputBindKey(&m_inputMap, type, key, gbaKey);
|
||||
}
|
||||
|
||||
#ifdef BUILD_SDL
|
||||
int InputController::testSDLEvents() {
|
||||
SDL_Joystick* joystick = m_sdlEvents.joystick;
|
||||
|
@ -25,6 +25,10 @@ public:
|
||||
|
||||
GBAKey mapKeyboard(int key) const;
|
||||
|
||||
void bindKey(uint32_t type, int key, GBAKey);
|
||||
|
||||
const GBAInputMap* map() const { return &m_inputMap; }
|
||||
|
||||
#ifdef BUILD_SDL
|
||||
int testSDLEvents();
|
||||
#endif
|
||||
|
28
src/platform/qt/KeyEditor.cpp
Normal file
28
src/platform/qt/KeyEditor.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "KeyEditor.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
KeyEditor::KeyEditor(QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void KeyEditor::setValue(int key) {
|
||||
setText(QKeySequence(key).toString(QKeySequence::NativeText));
|
||||
m_key = key;
|
||||
emit valueChanged(key);
|
||||
}
|
||||
|
||||
QSize KeyEditor::sizeHint() const {
|
||||
QSize hint = QLineEdit::sizeHint();
|
||||
hint.setWidth(40);
|
||||
return hint;
|
||||
}
|
||||
|
||||
void KeyEditor::keyPressEvent(QKeyEvent* event) {
|
||||
setValue(event->key());
|
||||
event->accept();
|
||||
}
|
31
src/platform/qt/KeyEditor.h
Normal file
31
src/platform/qt/KeyEditor.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef QGBA_KEY_EDITOR
|
||||
#define QGBA_KEY_EDITOR
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class KeyEditor : public QLineEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KeyEditor(QWidget* parent = nullptr);
|
||||
|
||||
void setValue(int key);
|
||||
int value() const { return m_key; }
|
||||
|
||||
virtual QSize sizeHint() const override;
|
||||
|
||||
signals:
|
||||
void valueChanged(int key);
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
private:
|
||||
int m_key;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ConfigController.h"
|
||||
#include "GameController.h"
|
||||
#include "GBAKeyEditor.h"
|
||||
#include "GDBController.h"
|
||||
#include "GDBWindow.h"
|
||||
#include "LoadSaveState.h"
|
||||
@ -136,6 +137,13 @@ void Window::selectPatch() {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::openKeymapWindow() {
|
||||
GBAKeyEditor* keyEditor = new GBAKeyEditor(&m_inputController, InputController::KEYBOARD);
|
||||
connect(this, SIGNAL(shutdown()), keyEditor, SLOT(close()));
|
||||
keyEditor->setAttribute(Qt::WA_DeleteOnClose);
|
||||
keyEditor->show();
|
||||
}
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
void Window::openVideoWindow() {
|
||||
if (!m_videoView) {
|
||||
@ -395,6 +403,11 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||
audioSync->connect([this](const QVariant& value) { m_controller->setAudioSync(value.toBool()); });
|
||||
m_config->updateOption("audioSync");
|
||||
|
||||
emulationMenu->addSeparator();
|
||||
QAction* keymap = new QAction(tr("Remap keyboard..."), emulationMenu);
|
||||
connect(keymap, SIGNAL(triggered()), this, SLOT(openKeymapWindow()));
|
||||
emulationMenu->addAction(keymap);
|
||||
|
||||
QMenu* videoMenu = menubar->addMenu(tr("&Video"));
|
||||
QMenu* frameMenu = videoMenu->addMenu(tr("Frame size"));
|
||||
QAction* setSize = new QAction(tr("1x"), videoMenu);
|
||||
|
@ -50,6 +50,8 @@ public slots:
|
||||
void loadConfig();
|
||||
void saveConfig();
|
||||
|
||||
void openKeymapWindow();
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
void openVideoWindow();
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>../../../res/mgba-1024.png</file>
|
||||
<file>../../../res/keymap.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
Reference in New Issue
Block a user