mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #21566 from hrydgard/modifier-keys
Add Ctrl+Tab / Ctrl+Shift+Tab to change tabs in the UI
This commit is contained in:
@@ -165,13 +165,23 @@ struct TouchInput {
|
||||
double timestamp;
|
||||
};
|
||||
|
||||
#undef MOD_CTRL
|
||||
#undef MOD_ALT
|
||||
#undef MOD_SHIFT
|
||||
|
||||
enum class KeyInputFlags {
|
||||
DOWN = 1 << 0,
|
||||
UP = 1 << 1,
|
||||
HAS_WHEEL_DELTA = 1 << 2,
|
||||
IS_REPEAT = 1 << 3,
|
||||
CHAR = 1 << 4, // Unicode character input. Cannot detect keyups of these so KeyInputFlags::DOWN and KeyInputFlags::UP are zero when this is set.
|
||||
|
||||
// NOTE: These are only available in sync input.
|
||||
MOD_CTRL = 1 << 5,
|
||||
MOD_SHIFT = 1 << 6,
|
||||
MOD_ALT = 1 << 7,
|
||||
};
|
||||
|
||||
ENUM_CLASS_BITOPS(KeyInputFlags);
|
||||
|
||||
struct KeyInput {
|
||||
|
||||
@@ -333,6 +333,24 @@ bool ChoiceStrip::Key(const KeyInput &input) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Support Ctrl+Tab / Ctrl+Shift+Tab as well, as these are common shortcuts for tab switching even outside of browsers.
|
||||
if (input.keyCode == NKCODE_TAB && (input.flags & KeyInputFlags::MOD_CTRL)) {
|
||||
if (input.flags & KeyInputFlags::MOD_SHIFT) {
|
||||
if (selected_ > 0) {
|
||||
SetSelection(selected_ - 1, true);
|
||||
} else if (!choices_.empty()) {
|
||||
SetSelection(choices_.size() - 1, true);
|
||||
}
|
||||
} else {
|
||||
if (selected_ < (int)choices_.size() - 1) {
|
||||
SetSelection(selected_ + 1, true);
|
||||
} else {
|
||||
SetSelection(0, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ViewGroup::Key(input);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
|
||||
@@ -130,9 +130,41 @@ bool UIScreen::UnsyncKey(const KeyInput &key) {
|
||||
}
|
||||
}
|
||||
|
||||
// Track modifier keys.
|
||||
if (key.flags & KeyInputFlags::DOWN) {
|
||||
switch (key.keyCode) {
|
||||
case NKCODE_CTRL_LEFT: modifiersPressed_ |= Modifier::LCTRL; break;
|
||||
case NKCODE_CTRL_RIGHT: modifiersPressed_ |= Modifier::RCTRL; break;
|
||||
case NKCODE_SHIFT_LEFT: modifiersPressed_ |= Modifier::LSHIFT; break;
|
||||
case NKCODE_SHIFT_RIGHT: modifiersPressed_ |= Modifier::RSHIFT; break;
|
||||
case NKCODE_ALT_LEFT: modifiersPressed_ |= Modifier::LALT; break;
|
||||
case NKCODE_ALT_RIGHT: modifiersPressed_ |= Modifier::RALT; break;
|
||||
}
|
||||
}
|
||||
if (key.flags & KeyInputFlags::UP) {
|
||||
switch (key.keyCode) {
|
||||
case NKCODE_CTRL_LEFT: modifiersPressed_ &= ~Modifier::LCTRL; break;
|
||||
case NKCODE_CTRL_RIGHT: modifiersPressed_ &= ~Modifier::RCTRL; break;
|
||||
case NKCODE_SHIFT_LEFT: modifiersPressed_ &= ~Modifier::LSHIFT; break;
|
||||
case NKCODE_SHIFT_RIGHT: modifiersPressed_ &= ~Modifier::RSHIFT; break;
|
||||
case NKCODE_ALT_LEFT: modifiersPressed_ &= ~Modifier::LALT; break;
|
||||
case NKCODE_ALT_RIGHT: modifiersPressed_ &= ~Modifier::RALT; break;
|
||||
}
|
||||
}
|
||||
|
||||
QueuedEvent ev{};
|
||||
ev.type = QueuedEventType::KEY;
|
||||
ev.key = key;
|
||||
|
||||
if (modifiersPressed_ & (Modifier::LCTRL | Modifier::RCTRL)) {
|
||||
ev.key.flags |= KeyInputFlags::MOD_CTRL;
|
||||
}
|
||||
if (modifiersPressed_ & (Modifier::LSHIFT | Modifier::RSHIFT)) {
|
||||
ev.key.flags |= KeyInputFlags::MOD_SHIFT;
|
||||
}
|
||||
if (modifiersPressed_ & (Modifier::LALT | Modifier::RALT)) {
|
||||
ev.key.flags |= KeyInputFlags::MOD_ALT;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(eventQueueLock_);
|
||||
eventQueue_.push_back(ev);
|
||||
return retval;
|
||||
|
||||
@@ -32,6 +32,17 @@ struct QueuedEvent {
|
||||
};
|
||||
};
|
||||
|
||||
enum class Modifier {
|
||||
NONE = 0,
|
||||
LCTRL = 1,
|
||||
RCTRL = 2,
|
||||
LSHIFT = 4,
|
||||
RSHIFT = 8,
|
||||
LALT = 16,
|
||||
RALT = 32,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(Modifier);
|
||||
|
||||
class UIScreen : public Screen {
|
||||
public:
|
||||
UIScreen();
|
||||
@@ -61,6 +72,10 @@ public:
|
||||
|
||||
virtual UI::Margins RootMargins() const { return UI::Margins(0); }
|
||||
|
||||
virtual void focusChanged(ScreenFocusChange focusChange) {
|
||||
modifiersPressed_ = Modifier::NONE;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void CreateViews() = 0;
|
||||
|
||||
@@ -90,6 +105,8 @@ protected:
|
||||
private:
|
||||
std::mutex eventQueueLock_;
|
||||
std::deque<QueuedEvent> eventQueue_;
|
||||
|
||||
Modifier modifiersPressed_{};
|
||||
};
|
||||
|
||||
class UIDialogScreen : public UIScreen {
|
||||
|
||||
+4
-3
@@ -317,9 +317,10 @@ static const ConfigSetting generalSettings[] = {
|
||||
ConfigSetting("UITint", SETTING(g_Config, fUITint), 0.0, CfgFlag::DEFAULT),
|
||||
ConfigSetting("UISaturation", SETTING(g_Config, fUISaturation), &DefaultUISaturation, CfgFlag::DEFAULT),
|
||||
|
||||
// Current tabs
|
||||
ConfigSetting("SettingsCurrentTab", SETTING(g_Config, iSettingsCurrentTab), 0, CfgFlag::DEFAULT),
|
||||
ConfigSetting("DeveloperSettingsCurrentTab", SETTING(g_Config, iDeveloperSettingsCurrentTab), 0, CfgFlag::DEFAULT),
|
||||
// Current settings tabs
|
||||
// Decided for now that these should not be saved, so commented out from here. Still saved within the session, of course.
|
||||
// ConfigSetting("SettingsCurrentTab", SETTING(g_Config, iSettingsCurrentTab), 0, CfgFlag::DEFAULT),
|
||||
// ConfigSetting("DeveloperSettingsCurrentTab", SETTING(g_Config, iDeveloperSettingsCurrentTab), 0, CfgFlag::DEFAULT),
|
||||
|
||||
#if defined(USING_WIN_UI)
|
||||
ConfigSetting("TopMost", SETTING(g_Config, bTopMost), false, CfgFlag::DEFAULT),
|
||||
|
||||
Reference in New Issue
Block a user