This commit is contained in:
David Capello 2025-09-01 21:37:16 +00:00 committed by GitHub
commit 1e29f1d606
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 144 additions and 63 deletions

View File

@ -94,6 +94,7 @@ protected:
void onInitTheme(InitThemeEvent& ev) override;
LayoutIO* onGetLayoutIO() override { return this; }
void onNewDisplayConfiguration(Display* display) override;
bool onEnqueueMouseDown(MouseMessage* mouseMsg) override;
// LayoutIO implementation
std::string loadLayout(Widget* widget) override;
@ -678,6 +679,23 @@ void CustomizedGuiManager::onNewDisplayConfiguration(Display* display)
}
}
bool CustomizedGuiManager::onEnqueueMouseDown(MouseMessage* mouseMsg)
{
ASSERT(mouseMsg->type() == kMouseDownMessage);
// If there is no modal window running...
App* app = App::instance();
if (app && getForegroundWindow() == app->mainWindow()) {
// Process a mouse button as a shortcut.
if (processKey(mouseMsg)) {
// Don't enqueue this message
return false;
}
}
return true;
}
bool CustomizedGuiManager::processKey(Message* msg)
{
App* app = App::instance();

View File

@ -499,6 +499,7 @@ const ui::Shortcut* Key::isPressed(const Message* msg, const KeyContext keyConte
else if (const auto* mouseMsg = dynamic_cast<const MouseMessage*>(msg)) {
for (const Shortcut& shortcut : shortcuts()) {
if ((shortcut.modifiers() == mouseMsg->modifiers()) &&
(shortcut.mouseButton() == mouseMsg->button()) &&
(m_keycontext == KeyContext::Any ||
// TODO we could have multiple mouse wheel key-context,
// like "sprite editor" context, or "timeline" context,

View File

@ -56,19 +56,21 @@ protected:
if (keymsg->scancode() == kKeySpace)
modifiers = (KeyModifiers)(modifiers & ~kKeySpaceModifier);
m_shortcut = Shortcut(
modifiers,
setAndParseShortcut(
Shortcut(modifiers,
keymsg->scancode(),
keymsg->unicodeChar() > 32 ? std::tolower(keymsg->unicodeChar()) : 0);
keymsg->unicodeChar() > 32 ? std::tolower(keymsg->unicodeChar()) : 0));
// Convert the shortcut to a string, and parse it
// again. Just to obtain the exact shortcut we'll read
// when we import the gui.xml file or an .aseprite-keys file.
m_shortcut = Shortcut(m_shortcut.toString());
return true;
}
break;
updateText();
case kMouseDownMessage:
if (!isReadOnly()) {
auto* mouseMsg = static_cast<MouseMessage*>(msg);
const KeyModifiers modifiers = mouseMsg->modifiers();
ShortcutChange(&m_shortcut);
setAndParseShortcut(Shortcut(modifiers, mouseMsg->button()));
return true;
}
break;
@ -76,9 +78,23 @@ protected:
return Entry::onProcessMessage(msg);
}
void setAndParseShortcut(const Shortcut& shortcut)
{
// Convert the shortcut to a string, and parse it
// again. Just to obtain the exact shortcut we'll read
// when we import the gui.xml file or an .aseprite-keys file.
m_shortcut = Shortcut(shortcut.toString());
updateText();
ShortcutChange(&m_shortcut);
}
void updateText()
{
setText(Shortcut(kKeyNoneModifier, m_shortcut.scancode(), m_shortcut.unicodeChar()).toString());
Shortcut tmp = m_shortcut;
tmp.removeModifiers();
setText(tmp.toString());
}
private:
@ -121,11 +137,15 @@ void SelectShortcut::onModifierChange(KeyModifiers modifier, CheckBox* checkbox)
KeyModifiers modifiers = m_shortcut.modifiers();
KeyScancode scancode = m_shortcut.scancode();
int unicodeChar = m_shortcut.unicodeChar();
MouseButton mouseButton = m_shortcut.mouseButton();
modifiers = (KeyModifiers)((modifiers & ~modifier) | (state ? modifier : 0));
if (modifiers == kKeySpaceModifier && scancode == kKeySpace)
modifiers = kKeyNoneModifier;
if (mouseButton != kButtonNone)
m_shortcut = Shortcut(modifiers, mouseButton);
else
m_shortcut = Shortcut(modifiers, scancode, unicodeChar);
m_keyField->setShortcut(m_shortcut);

View File

@ -652,7 +652,8 @@ void Manager::handleMouseDown(Display* display,
if (!handleWindowZOrder())
return;
enqueueMessage(newMouseMessage(kMouseDownMessage,
std::unique_ptr<MouseMessage> mouseMsg(
newMouseMessage(kMouseDownMessage,
display,
(capture_widget ? capture_widget : mouse_widget),
mousePos,
@ -662,6 +663,9 @@ void Manager::handleMouseDown(Display* display,
gfx::Point(0, 0),
false,
pressure));
if (onEnqueueMouseDown(mouseMsg.get()))
enqueueMessage(mouseMsg.release());
}
void Manager::handleMouseUp(Display* display,
@ -1847,6 +1851,11 @@ void Manager::onNewDisplayConfiguration(Display* display)
container->flushRedraw();
}
bool Manager::onEnqueueMouseDown(MouseMessage* mouseMsg)
{
return true;
}
void Manager::onSizeHint(SizeHintEvent& ev)
{
int w = 0, h = 0;
@ -2270,7 +2279,7 @@ Widget* Manager::findMagneticWidget(Widget* widget)
}
// static
Message* Manager::newMouseMessage(MessageType type,
MouseMessage* Manager::newMouseMessage(MessageType type,
Display* display,
Widget* widget,
const gfx::Point& mousePos,
@ -2290,7 +2299,7 @@ Message* Manager::newMouseMessage(MessageType type,
}
#endif
Message* msg = new MouseMessage(type,
auto* msg = new MouseMessage(type,
pointerType,
button,
modifiers,

View File

@ -150,6 +150,7 @@ protected:
void onInitTheme(InitThemeEvent& ev) override;
virtual LayoutIO* onGetLayoutIO();
virtual void onNewDisplayConfiguration(Display* display);
virtual bool onEnqueueMouseDown(MouseMessage* mouseMsg);
private:
void generateSetCursorMessage(Display* display,
@ -205,7 +206,7 @@ private:
static Widget* findLowestCommonAncestor(Widget* a, Widget* b);
static bool someParentIsFocusStop(Widget* widget);
static Widget* findMagneticWidget(Widget* widget);
static Message* newMouseMessage(MessageType type,
static MouseMessage* newMouseMessage(MessageType type,
Display* display,
Widget* widget,
const gfx::Point& mousePos,

View File

@ -144,7 +144,7 @@ int scancode_to_string_size = sizeof(scancode_to_string) / sizeof(scancode_to_st
} // anonymous namespace
Shortcut::Shortcut() : m_modifiers(kKeyNoneModifier), m_scancode(kKeyNil), m_unicodeChar(0)
Shortcut::Shortcut()
{
}
@ -155,10 +155,13 @@ Shortcut::Shortcut(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar
{
}
Shortcut::Shortcut(KeyModifiers modifiers, MouseButton mouseButton)
: m_modifiers(modifiers)
, m_mouseButton(mouseButton)
{
}
Shortcut::Shortcut(const std::string& str)
: m_modifiers(kKeyNoneModifier)
, m_scancode(kKeyNil)
, m_unicodeChar(0)
{
// Special case: plus sign
if (str == "+") {
@ -272,6 +275,16 @@ Shortcut::Shortcut(const std::string& str)
m_scancode = kKeyDelPad;
else if (tok == "enter pad")
m_scancode = kKeyEnterPad;
else if (tok == "left mouse button")
m_mouseButton = kButtonLeft;
else if (tok == "right mouse button")
m_mouseButton = kButtonRight;
else if (tok == "middle mouse button")
m_mouseButton = kButtonMiddle;
else if (tok == "x1 mouse button")
m_mouseButton = kButtonX1;
else if (tok == "x2 mouse button")
m_mouseButton = kButtonX2;
}
}
@ -313,10 +326,23 @@ std::string Shortcut::toString() const
wideUnicodeChar.push_back((wchar_t)std::toupper(m_unicodeChar));
buf += base::to_utf8(wideUnicodeChar);
}
else if (m_scancode > 0 && m_scancode < scancode_to_string_size && scancode_to_string[m_scancode])
else if (m_scancode > 0 && m_scancode < scancode_to_string_size &&
scancode_to_string[m_scancode]) {
buf += scancode_to_string[m_scancode];
else if (!buf.empty() && buf[buf.size() - 1] == '+')
}
// Mouse button
else if (m_mouseButton != kButtonNone) {
switch (m_mouseButton) {
case kButtonLeft: buf += "Left Mouse Button"; break;
case kButtonRight: buf += "Right Mouse Button"; break;
case kButtonMiddle: buf += "Middle Mouse Button"; break;
case kButtonX1: buf += "X1 Mouse Button"; break;
case kButtonX2: buf += "X2 Mouse Button"; break;
}
}
else if (!buf.empty() && buf[buf.size() - 1] == '+') {
buf.erase(buf.size() - 1);
}
return buf;
}
@ -336,7 +362,7 @@ bool Shortcut::isPressed() const
KeyModifiers pressedModifiers = sys->keyModifiers();
// Check if this shortcut is only
if (m_scancode == kKeyNil && m_unicodeChar == 0)
if (m_scancode == kKeyNil && m_unicodeChar == 0 && m_mouseButton == kButtonNone)
return (m_modifiers == pressedModifiers);
// Compare with all pressed scancodes
@ -361,7 +387,7 @@ bool Shortcut::isLooselyPressed() const
return false;
// Check if this shortcut is only
if (m_scancode == kKeyNil && m_unicodeChar == 0)
if (m_scancode == kKeyNil && m_unicodeChar == 0 && m_mouseButton == kButtonNone)
return true;
// Compare with all pressed scancodes

View File

@ -9,11 +9,12 @@
#define UI_SHORTCUT_H_INCLUDED
#pragma once
#include "ui/keys.h"
#include "ui/mouse_button.h"
#include <string>
#include <vector>
#include "ui/keys.h"
namespace ui {
extern const char* kWinKeyName;
@ -22,6 +23,7 @@ class Shortcut {
public:
Shortcut();
Shortcut(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar);
Shortcut(KeyModifiers modifiers, MouseButton mouseButton);
// Convert string like "Ctrl+Q" or "Alt+X" into an shortcut.
explicit Shortcut(const std::string& str);
@ -44,11 +46,15 @@ public:
KeyModifiers modifiers() const { return m_modifiers; }
KeyScancode scancode() const { return m_scancode; }
int unicodeChar() const { return m_unicodeChar; }
MouseButton mouseButton() const { return m_mouseButton; }
void removeModifiers() { m_modifiers = kKeyNoneModifier; }
private:
KeyModifiers m_modifiers;
KeyScancode m_scancode;
int m_unicodeChar;
KeyModifiers m_modifiers = kKeyNoneModifier;
KeyScancode m_scancode = kKeyNil;
int m_unicodeChar = 0;
MouseButton m_mouseButton = kButtonNone;
};
class Shortcuts {