Fix Left/Right keys to move through frames in FramesSelection context (fix #3821)

This commit is contained in:
David Capello 2023-04-25 10:38:49 -03:00
parent a9207524ff
commit 9b76f95b15
3 changed files with 90 additions and 66 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2022 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -714,77 +714,84 @@ bool CustomizedGuiManager::processKey(Message* msg)
{
App* app = App::instance();
const KeyboardShortcuts* keys = KeyboardShortcuts::instance();
for (const KeyPtr& key : *keys) {
if (key->isPressed(msg, *keys)) {
// Cancel menu-bar loops (to close any popup menu)
app->mainWindow()->getMenuBar()->cancelMenuLoop();
const KeyContext contexts[] = {
keys->getCurrentKeyContext(),
KeyContext::Normal
};
int n = (contexts[0] != contexts[1] ? 2: 1);
for (int i = 0; i < n; ++i) {
for (const KeyPtr& key : *keys) {
if (key->isPressed(msg, *keys, contexts[i])) {
// Cancel menu-bar loops (to close any popup menu)
app->mainWindow()->getMenuBar()->cancelMenuLoop();
switch (key->type()) {
switch (key->type()) {
case KeyType::Tool: {
tools::Tool* current_tool = app->activeTool();
tools::Tool* select_this_tool = key->tool();
tools::ToolBox* toolbox = app->toolBox();
std::vector<tools::Tool*> possibles;
case KeyType::Tool: {
tools::Tool* current_tool = app->activeTool();
tools::Tool* select_this_tool = key->tool();
tools::ToolBox* toolbox = app->toolBox();
std::vector<tools::Tool*> possibles;
// Collect all tools with the pressed keyboard-shortcut
for (tools::Tool* tool : *toolbox) {
const KeyPtr key = keys->tool(tool);
if (key && key->isPressed(msg, *keys))
possibles.push_back(tool);
}
if (possibles.size() >= 2) {
bool done = false;
for (size_t i=0; i<possibles.size(); ++i) {
if (possibles[i] != current_tool &&
ToolBar::instance()->isToolVisible(possibles[i])) {
select_this_tool = possibles[i];
done = true;
break;
}
// Collect all tools with the pressed keyboard-shortcut
for (tools::Tool* tool : *toolbox) {
const KeyPtr key = keys->tool(tool);
if (key && key->isPressed(msg, *keys))
possibles.push_back(tool);
}
if (!done) {
if (possibles.size() >= 2) {
bool done = false;
for (size_t i=0; i<possibles.size(); ++i) {
// If one of the possibilities is the current tool
if (possibles[i] == current_tool) {
// We select the next tool in the possibilities
select_this_tool = possibles[(i+1) % possibles.size()];
if (possibles[i] != current_tool &&
ToolBar::instance()->isToolVisible(possibles[i])) {
select_this_tool = possibles[i];
done = true;
break;
}
}
if (!done) {
for (size_t i=0; i<possibles.size(); ++i) {
// If one of the possibilities is the current tool
if (possibles[i] == current_tool) {
// We select the next tool in the possibilities
select_this_tool = possibles[(i+1) % possibles.size()];
break;
}
}
}
}
}
ToolBar::instance()->selectTool(select_this_tool);
return true;
}
case KeyType::Command: {
Command* command = key->command();
// Commands are executed only when the main window is
// the current window running.
if (getForegroundWindow() == app->mainWindow()) {
// OK, so we can execute the command represented
// by the pressed-key in the message...
UIContext::instance()->executeCommandFromMenuOrShortcut(
command, key->params());
ToolBar::instance()->selectTool(select_this_tool);
return true;
}
break;
}
case KeyType::Quicktool: {
// Do nothing, it is used in the editor through the
// KeyboardShortcuts::getCurrentQuicktool() function.
break;
}
case KeyType::Command: {
Command* command = key->command();
// Commands are executed only when the main window is
// the current window running.
if (getForegroundWindow() == app->mainWindow()) {
// OK, so we can execute the command represented
// by the pressed-key in the message...
UIContext::instance()->executeCommandFromMenuOrShortcut(
command, key->params());
return true;
}
break;
}
case KeyType::Quicktool: {
// Do nothing, it is used in the editor through the
// KeyboardShortcuts::getCurrentQuicktool() function.
break;
}
}
break;
}
break;
}
}
return false;

View File

@ -131,6 +131,9 @@ namespace app {
void add(const ui::Accelerator& accel,
const KeySource source,
KeyboardShortcuts& globalKeys);
const ui::Accelerator* isPressed(const ui::Message* msg,
const KeyboardShortcuts& globalKeys,
const KeyContext keyContext) const;
const ui::Accelerator* isPressed(const ui::Message* msg,
const KeyboardShortcuts& globalKeys) const;
bool isPressed() const;

View File

@ -435,17 +435,16 @@ void Key::add(const ui::Accelerator& accel,
}
const ui::Accelerator* Key::isPressed(const Message* msg,
const KeyboardShortcuts& globalKeys) const
const KeyboardShortcuts& globalKeys,
const KeyContext keyContext) const
{
const KeyContext currentKeyContext = globalKeys.getCurrentKeyContext();
if (auto keyMsg = dynamic_cast<const KeyMessage*>(msg)) {
for (const Accelerator& accel : accels()) {
if (accel.isPressed(keyMsg->modifiers(),
keyMsg->scancode(),
keyMsg->unicodeChar()) &&
(m_keycontext == KeyContext::Any ||
m_keycontext == currentKeyContext)) {
m_keycontext == keyContext)) {
return &accel;
}
}
@ -465,6 +464,14 @@ const ui::Accelerator* Key::isPressed(const Message* msg,
return nullptr;
}
const ui::Accelerator* Key::isPressed(const Message* msg,
const KeyboardShortcuts& globalKeys) const
{
return isPressed(msg,
globalKeys,
globalKeys.getCurrentKeyContext());
}
bool Key::isPressed() const
{
for (const Accelerator& accel : this->accels()) {
@ -1104,12 +1111,19 @@ KeyContext KeyboardShortcuts::getCurrentKeyContext() const
bool KeyboardShortcuts::getCommandFromKeyMessage(const Message* msg, Command** command, Params* params)
{
for (KeyPtr& key : m_keys) {
if (key->type() == KeyType::Command &&
key->isPressed(msg, *this)) {
if (command) *command = key->command();
if (params) *params = key->params();
return true;
const KeyContext contexts[] = {
getCurrentKeyContext(),
KeyContext::Normal
};
int n = (contexts[0] != contexts[1] ? 2: 1);
for (int i = 0; i < n; ++i) {
for (KeyPtr& key : m_keys) {
if (key->type() == KeyType::Command &&
key->isPressed(msg, *this, contexts[i])) {
if (command) *command = key->command();
if (params) *params = key->params();
return true;
}
}
}
return false;