Use BitField<> in core type masks

* All core types masks are now correctly marked as bitfields.
* The enum hacks in MouseButtonMask and many other types are gone. This ensures that binders to other languages non C++ can actually implement type safe bitmasks.
* Most bitmask operations replaced by functions in BitField<>
* Key is still a problem because its enum and mask at the same time. While it kind of works in C++, this most likely can't be implemented safely in other languages and will have to be changed at some point. Mostly left as-is.
* Documentation and API dump updated to reflect bitfields in core types.
This commit is contained in:
Juan Linietsky 2023-01-08 00:55:54 +01:00
parent fcba87e696
commit 2b815df3c1
69 changed files with 490 additions and 442 deletions

View File

@ -39,6 +39,7 @@ struct _CoreConstant {
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
StringName enum_name; StringName enum_name;
bool ignore_value_in_docs = false; bool ignore_value_in_docs = false;
bool is_bitfield = false;
#endif #endif
const char *name = nullptr; const char *name = nullptr;
int64_t value = 0; int64_t value = 0;
@ -46,9 +47,10 @@ struct _CoreConstant {
_CoreConstant() {} _CoreConstant() {}
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
_CoreConstant(const StringName &p_enum_name, const char *p_name, int64_t p_value, bool p_ignore_value_in_docs = false) : _CoreConstant(const StringName &p_enum_name, const char *p_name, int64_t p_value, bool p_ignore_value_in_docs = false, bool p_is_bitfield = false) :
enum_name(p_enum_name), enum_name(p_enum_name),
ignore_value_in_docs(p_ignore_value_in_docs), ignore_value_in_docs(p_ignore_value_in_docs),
is_bitfield(p_is_bitfield),
name(p_name), name(p_name),
value(p_value) { value(p_value) {
} }
@ -70,13 +72,22 @@ static Vector<_CoreConstant> _global_constants;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \ #define BIND_CORE_ENUM_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant)); _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant));
#define BIND_CORE_BITFIELD_FLAG(m_constant) \
_global_constants.push_back(_CoreConstant(__constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, false, true));
// This just binds enum classes as if they were regular enum constants. // This just binds enum classes as if they were regular enum constants.
#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int64_t)m_enum::m_member)); _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int64_t)m_enum::m_member));
#define BIND_CORE_BITFIELD_CLASS_FLAG(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(__constant_get_bitfield_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int64_t)m_enum::m_member, false, true));
#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_name), #m_name, (int64_t)m_enum::m_member)); _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_name), #m_name, (int64_t)m_enum::m_member));
#define BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(m_enum, m_name, m_member) \
_global_constants.push_back(_CoreConstant(__constant_get_bitfield_name(m_enum::m_member, #m_name), #m_name, (int64_t)m_enum::m_member, false, true));
#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int64_t)m_enum::m_member, true)); _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int64_t)m_enum::m_member, true));
@ -100,13 +111,22 @@ static Vector<_CoreConstant> _global_constants;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \ #define BIND_CORE_ENUM_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(#m_constant, m_constant)); _global_constants.push_back(_CoreConstant(#m_constant, m_constant));
#define BIND_CORE_BITFIELD_FLAG(m_constant) \
_global_constants.push_back(_CoreConstant(#m_constant, m_constant));
// This just binds enum classes as if they were regular enum constants. // This just binds enum classes as if they were regular enum constants.
#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int64_t)m_enum::m_member)); _global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int64_t)m_enum::m_member));
#define BIND_CORE_BITFIELD_CLASS_FLAG(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int64_t)m_enum::m_member));
#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
_global_constants.push_back(_CoreConstant(#m_name, (int64_t)m_enum::m_member)); _global_constants.push_back(_CoreConstant(#m_name, (int64_t)m_enum::m_member));
#define BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(m_enum, m_name, m_member) \
_global_constants.push_back(_CoreConstant(#m_name, (int64_t)m_enum::m_member));
#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \ #define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
_global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int64_t)m_enum::m_member)); _global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int64_t)m_enum::m_member));
@ -439,15 +459,15 @@ void register_global_constants() {
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIVISION); BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIVISION);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YDIAERESIS); BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YDIAERESIS);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK); BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK); BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, CMD_OR_CTRL); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CMD_OR_CTRL);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, SHIFT); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, SHIFT);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, ALT); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, ALT);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, META); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, META);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, CTRL); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CTRL);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, KPAD); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, KPAD);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, GROUP_SWITCH); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, GROUP_SWITCH);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, NONE); BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, NONE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT); BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT);
@ -459,11 +479,12 @@ void register_global_constants() {
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_RIGHT); BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON1, MB_XBUTTON1); BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON1, MB_XBUTTON1);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON2, MB_XBUTTON2); BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON2, MB_XBUTTON2);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_RIGHT); BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_MIDDLE); BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON1); BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MIDDLE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON2); BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON1);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON2);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, INVALID); BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, INVALID);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, A); BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, A);
@ -622,50 +643,50 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NONE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORAGE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_GROUP); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_GROUP);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CATEGORY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SUBGROUP);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CLASS_IS_BITFIELD); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_BITFIELD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_VARIABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NULL); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORE_IF_NULL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CLASS_IS_ENUM); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_ENUM);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NIL_IS_VARIANT); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NIL_IS_VARIANT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNAL); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_INTERNAL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_HIGH_END_GFX); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_HIGH_END_GFX);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_KEYING_INCREMENTS); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_KEYING_INCREMENTS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFERRED_SET_RESOURCE); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFERRED_SET_RESOURCE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_BASIC_SETTING); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_READ_ONLY); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_READ_ONLY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_ARRAY); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_ARRAY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT_INTL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_EDITOR); BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_EDITOR);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NORMAL); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_NORMAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_EDITOR); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_EDITOR);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_CONST); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_CONST);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VIRTUAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VARARG); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VARARG);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_STATIC);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE); BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); BIND_CORE_BITFIELD_FLAG(METHOD_FLAGS_DEFAULT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL);
@ -753,6 +774,10 @@ StringName CoreConstants::get_global_constant_enum(int p_idx) {
return _global_constants[p_idx].enum_name; return _global_constants[p_idx].enum_name;
} }
bool CoreConstants::is_global_constant_bitfield(int p_idx) {
return _global_constants[p_idx].is_bitfield;
}
bool CoreConstants::get_ignore_value_in_docs(int p_idx) { bool CoreConstants::get_ignore_value_in_docs(int p_idx) {
return _global_constants[p_idx].ignore_value_in_docs; return _global_constants[p_idx].ignore_value_in_docs;
} }
@ -761,6 +786,10 @@ StringName CoreConstants::get_global_constant_enum(int p_idx) {
return StringName(); return StringName();
} }
bool CoreConstants::is_global_constant_bitfield(int p_idx) {
return false;
}
bool CoreConstants::get_ignore_value_in_docs(int p_idx) { bool CoreConstants::get_ignore_value_in_docs(int p_idx) {
return false; return false;
} }

View File

@ -37,6 +37,7 @@ class CoreConstants {
public: public:
static int get_global_constant_count(); static int get_global_constant_count();
static StringName get_global_constant_enum(int p_idx); static StringName get_global_constant_enum(int p_idx);
static bool is_global_constant_bitfield(int p_idx);
static bool get_ignore_value_in_docs(int p_idx); static bool get_ignore_value_in_docs(int p_idx);
static const char *get_global_constant_name(int p_idx); static const char *get_global_constant_name(int p_idx);
static int64_t get_global_constant_value(int p_idx); static int64_t get_global_constant_value(int p_idx);

View File

@ -463,12 +463,14 @@ Dictionary GDExtensionAPIDump::generate_extension_api() {
int64_t value = CoreConstants::get_global_constant_value(i); int64_t value = CoreConstants::get_global_constant_value(i);
String enum_name = CoreConstants::get_global_constant_enum(i); String enum_name = CoreConstants::get_global_constant_enum(i);
String name = CoreConstants::get_global_constant_name(i); String name = CoreConstants::get_global_constant_name(i);
bool bitfield = CoreConstants::is_global_constant_bitfield(i);
if (!enum_name.is_empty()) { if (!enum_name.is_empty()) {
enum_list[enum_name].push_back(Pair<String, int64_t>(name, value)); enum_list[enum_name].push_back(Pair<String, int64_t>(name, value));
} else { } else {
Dictionary d; Dictionary d;
d["name"] = name; d["name"] = name;
d["value"] = value; d["value"] = value;
d["is_bitfield"] = bitfield;
constants.push_back(d); constants.push_back(d);
} }
} }

View File

@ -237,7 +237,7 @@ bool Input::is_anything_pressed() const {
} }
return !keys_pressed.is_empty() || return !keys_pressed.is_empty() ||
!joy_buttons_pressed.is_empty() || !joy_buttons_pressed.is_empty() ||
mouse_button_mask > MouseButton::NONE; !mouse_button_mask.is_empty();
} }
bool Input::is_key_pressed(Key p_keycode) const { bool Input::is_key_pressed(Key p_keycode) const {
@ -252,7 +252,7 @@ bool Input::is_physical_key_pressed(Key p_keycode) const {
bool Input::is_mouse_button_pressed(MouseButton p_button) const { bool Input::is_mouse_button_pressed(MouseButton p_button) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
return (mouse_button_mask & mouse_button_to_mask(p_button)) != MouseButton::NONE; return mouse_button_mask.has_flag(mouse_button_to_mask(p_button));
} }
static JoyAxis _combine_device(JoyAxis p_value, int p_device) { static JoyAxis _combine_device(JoyAxis p_value, int p_device) {
@ -504,9 +504,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
if (mb.is_valid()) { if (mb.is_valid()) {
if (mb->is_pressed()) { if (mb->is_pressed()) {
mouse_button_mask |= mouse_button_to_mask(mb->get_button_index()); mouse_button_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
} else { } else {
mouse_button_mask &= ~mouse_button_to_mask(mb->get_button_index()); mouse_button_mask.clear_flag(mouse_button_to_mask(mb->get_button_index()));
} }
Point2 pos = mb->get_global_position(); Point2 pos = mb->get_global_position();
@ -534,7 +534,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Vector2 relative = mm->get_relative(); Vector2 relative = mm->get_relative();
mouse_velocity_track.update(relative); mouse_velocity_track.update(relative);
if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && (mm->get_button_mask() & MouseButton::LEFT) != MouseButton::NONE) { if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
Ref<InputEventScreenDrag> drag_event; Ref<InputEventScreenDrag> drag_event;
drag_event.instantiate(); drag_event.instantiate();
@ -585,11 +585,14 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
button_event->set_pressed(st->is_pressed()); button_event->set_pressed(st->is_pressed());
button_event->set_button_index(MouseButton::LEFT); button_event->set_button_index(MouseButton::LEFT);
button_event->set_double_click(st->is_double_tap()); button_event->set_double_click(st->is_double_tap());
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
if (st->is_pressed()) { if (st->is_pressed()) {
button_event->set_button_mask(MouseButton(mouse_button_mask | MouseButton::MASK_LEFT)); ev_bm.set_flag(MouseButtonMask::LEFT);
} else { } else {
button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT)); ev_bm.clear_flag(MouseButtonMask::LEFT);
} }
button_event->set_button_mask(ev_bm);
_parse_input_event_impl(button_event, true); _parse_input_event_impl(button_event, true);
} }
@ -740,7 +743,7 @@ Point2 Input::get_last_mouse_velocity() {
return mouse_velocity_track.velocity; return mouse_velocity_track.velocity;
} }
MouseButton Input::get_mouse_button_mask() const { BitField<MouseButtonMask> Input::get_mouse_button_mask() const {
return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state(); return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
} }
@ -821,7 +824,9 @@ void Input::ensure_touch_mouse_raised() {
button_event->set_global_position(mouse_pos); button_event->set_global_position(mouse_pos);
button_event->set_pressed(false); button_event->set_pressed(false);
button_event->set_button_index(MouseButton::LEFT); button_event->set_button_index(MouseButton::LEFT);
button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT)); BitField<MouseButtonMask> ev_bm = mouse_button_mask;
ev_bm.clear_flag(MouseButtonMask::LEFT);
button_event->set_button_mask(ev_bm);
_parse_input_event_impl(button_event, true); _parse_input_event_impl(button_event, true);
} }
@ -1022,7 +1027,7 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) {
} }
} }
void Input::joy_hat(int p_device, HatMask p_val) { void Input::joy_hat(int p_device, BitField<HatMask> p_val) {
_THREAD_SAFE_METHOD_; _THREAD_SAFE_METHOD_;
const Joypad &joy = joy_names[p_device]; const Joypad &joy = joy_names[p_device];

View File

@ -82,7 +82,7 @@ public:
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event); typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
private: private:
MouseButton mouse_button_mask = MouseButton::NONE; BitField<MouseButtonMask> mouse_button_mask;
RBSet<Key> physical_keys_pressed; RBSet<Key> physical_keys_pressed;
RBSet<Key> keys_pressed; RBSet<Key> keys_pressed;
@ -273,7 +273,7 @@ public:
Point2 get_mouse_position() const; Point2 get_mouse_position() const;
Vector2 get_last_mouse_velocity(); Vector2 get_last_mouse_velocity();
MouseButton get_mouse_button_mask() const; BitField<MouseButtonMask> get_mouse_button_mask() const;
void warp_mouse(const Vector2 &p_position); void warp_mouse(const Vector2 &p_position);
Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect); Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
@ -310,7 +310,7 @@ public:
void parse_mapping(String p_mapping); void parse_mapping(String p_mapping);
void joy_button(int p_device, JoyButton p_button, bool p_pressed); void joy_button(int p_device, JoyButton p_button, bool p_pressed);
void joy_axis(int p_device, JoyAxis p_axis, float p_value); void joy_axis(int p_device, JoyAxis p_axis, float p_value);
void joy_hat(int p_device, HatMask p_val); void joy_hat(int p_device, BitField<HatMask> p_val);
void add_joy_mapping(String p_mapping, bool p_update_existing = false); void add_joy_mapping(String p_mapping, bool p_update_existing = false);
void remove_joy_mapping(String p_guid); void remove_joy_mapping(String p_guid);

View File

@ -119,59 +119,18 @@ enum class MouseButton {
WHEEL_RIGHT = 7, WHEEL_RIGHT = 7,
MB_XBUTTON1 = 8, // "XBUTTON1" is a reserved word on Windows. MB_XBUTTON1 = 8, // "XBUTTON1" is a reserved word on Windows.
MB_XBUTTON2 = 9, // "XBUTTON2" is a reserved word on Windows. MB_XBUTTON2 = 9, // "XBUTTON2" is a reserved word on Windows.
MASK_LEFT = (1 << (LEFT - 1)),
MASK_RIGHT = (1 << (RIGHT - 1)),
MASK_MIDDLE = (1 << (MIDDLE - 1)),
MASK_XBUTTON1 = (1 << (MB_XBUTTON1 - 1)),
MASK_XBUTTON2 = (1 << (MB_XBUTTON2 - 1)),
}; };
inline MouseButton mouse_button_to_mask(MouseButton button) { enum class MouseButtonMask {
return MouseButton(1 << ((int)button - 1)); LEFT = (1 << (int(MouseButton::LEFT) - 1)),
} RIGHT = (1 << (int(MouseButton::RIGHT) - 1)),
MIDDLE = (1 << (int(MouseButton::MIDDLE) - 1)),
MB_XBUTTON1 = (1 << (int(MouseButton::MB_XBUTTON1) - 1)),
MB_XBUTTON2 = (1 << (int(MouseButton::MB_XBUTTON2) - 1)),
};
inline MouseButton operator&(MouseButton a, MouseButton b) { inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
return (MouseButton)((int)a & (int)b); return MouseButtonMask(1 << ((int)button - 1));
}
inline MouseButton operator|(MouseButton a, MouseButton b) {
return (MouseButton)((int)a | (int)b);
}
inline MouseButton operator^(MouseButton a, MouseButton b) {
return (MouseButton)((int)a ^ (int)b);
}
inline MouseButton &operator|=(MouseButton &a, MouseButton b) {
return (MouseButton &)((int &)a |= (int)b);
}
inline MouseButton &operator&=(MouseButton &a, MouseButton b) {
return (MouseButton &)((int &)a &= (int)b);
}
inline MouseButton operator~(MouseButton a) {
return (MouseButton)(~(int)a);
}
inline HatMask operator|(HatMask a, HatMask b) {
return (HatMask)((int)a | (int)b);
}
inline HatMask operator&(HatMask a, HatMask b) {
return (HatMask)((int)a & (int)b);
}
inline HatMask &operator&=(HatMask &a, HatMask b) {
return (HatMask &)((int &)a &= (int)b);
}
inline HatMask &operator|=(HatMask &a, HatMask b) {
return (HatMask &)((int &)a |= (int)b);
}
inline HatMask operator~(HatMask a) {
return (HatMask)(~(int)a);
} }
#endif // INPUT_ENUMS_H #endif // INPUT_ENUMS_H

View File

@ -216,25 +216,25 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
set_meta_pressed(event->is_meta_pressed()); set_meta_pressed(event->is_meta_pressed());
} }
Key InputEventWithModifiers::get_modifiers_mask() const { BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
Key mask = Key::NONE; BitField<KeyModifierMask> mask;
if (is_ctrl_pressed()) { if (is_ctrl_pressed()) {
mask |= KeyModifierMask::CTRL; mask.set_flag(KeyModifierMask::CTRL);
} }
if (is_shift_pressed()) { if (is_shift_pressed()) {
mask |= KeyModifierMask::SHIFT; mask.set_flag(KeyModifierMask::SHIFT);
} }
if (is_alt_pressed()) { if (is_alt_pressed()) {
mask |= KeyModifierMask::ALT; mask.set_flag(KeyModifierMask::ALT);
} }
if (is_meta_pressed()) { if (is_meta_pressed()) {
mask |= KeyModifierMask::META; mask.set_flag(KeyModifierMask::META);
} }
if (is_command_or_control_autoremap()) { if (is_command_or_control_autoremap()) {
#ifdef MACOS_ENABLED #ifdef MACOS_ENABLED
mask |= KeyModifierMask::META; mask.set_flag(KeyModifierMask::META);
#else #else
mask |= KeyModifierMask::CTRL; mask.set_flag(KeyModifierMask::CTRL);
#endif #endif
} }
return mask; return mask;
@ -356,11 +356,11 @@ bool InputEventKey::is_echo() const {
} }
Key InputEventKey::get_keycode_with_modifiers() const { Key InputEventKey::get_keycode_with_modifiers() const {
return keycode | get_modifiers_mask(); return keycode | (int64_t)get_modifiers_mask();
} }
Key InputEventKey::get_physical_keycode_with_modifiers() const { Key InputEventKey::get_physical_keycode_with_modifiers() const {
return physical_keycode | get_modifiers_mask(); return physical_keycode | (int64_t)get_modifiers_mask();
} }
String InputEventKey::as_text() const { String InputEventKey::as_text() const {
@ -440,8 +440,8 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_ma
} else { } else {
match = get_physical_keycode() == key->get_physical_keycode(); match = get_physical_keycode() == key->get_physical_keycode();
} }
Key action_mask = get_modifiers_mask(); Key action_mask = (Key)(int64_t)get_modifiers_mask();
Key key_mask = key->get_modifiers_mask(); Key key_mask = (Key)(int64_t)key->get_modifiers_mask();
if (key->is_pressed()) { if (key->is_pressed()) {
match &= (action_mask & key_mask) == action_mask; match &= (action_mask & key_mask) == action_mask;
} }
@ -505,12 +505,12 @@ void InputEventKey::_bind_methods() {
/////////////////////////////////// ///////////////////////////////////
void InputEventMouse::set_button_mask(MouseButton p_mask) { void InputEventMouse::set_button_mask(BitField<MouseButtonMask> p_mask) {
button_mask = p_mask; button_mask = p_mask;
emit_changed(); emit_changed();
} }
MouseButton InputEventMouse::get_button_mask() const { BitField<MouseButtonMask> InputEventMouse::get_button_mask() const {
return button_mask; return button_mask;
} }
@ -610,8 +610,8 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool p_
} }
bool match = button_index == mb->button_index; bool match = button_index == mb->button_index;
Key action_modifiers_mask = get_modifiers_mask(); Key action_modifiers_mask = (Key)(int64_t)get_modifiers_mask();
Key button_modifiers_mask = mb->get_modifiers_mask(); Key button_modifiers_mask = (Key)(int64_t)mb->get_modifiers_mask();
if (mb->is_pressed()) { if (mb->is_pressed()) {
match &= (action_modifiers_mask & button_modifiers_mask) == action_modifiers_mask; match &= (action_modifiers_mask & button_modifiers_mask) == action_modifiers_mask;
} }
@ -808,26 +808,23 @@ String InputEventMouseMotion::as_text() const {
} }
String InputEventMouseMotion::to_string() { String InputEventMouseMotion::to_string() {
MouseButton mouse_button_mask = get_button_mask(); BitField<MouseButtonMask> mouse_button_mask = get_button_mask();
String button_mask_string = itos((int64_t)mouse_button_mask); String button_mask_string = itos((int64_t)mouse_button_mask);
switch (mouse_button_mask) {
case MouseButton::MASK_LEFT: if (mouse_button_mask.has_flag(MouseButtonMask::LEFT)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1])); button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]));
break; }
case MouseButton::MASK_MIDDLE: if (mouse_button_mask.has_flag(MouseButtonMask::MIDDLE)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1])); button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]));
break; }
case MouseButton::MASK_RIGHT: if (mouse_button_mask.has_flag(MouseButtonMask::RIGHT)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1])); button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]));
break; }
case MouseButton::MASK_XBUTTON1: if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON1)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1])); button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]));
break; }
case MouseButton::MASK_XBUTTON2: if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON2)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1])); button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]));
break;
default:
break;
} }
// Work around the fact vformat can only take 5 substitutions but 7 need to be passed. // Work around the fact vformat can only take 5 substitutions but 7 need to be passed.

View File

@ -138,7 +138,7 @@ public:
void set_modifiers_from_event(const InputEventWithModifiers *event); void set_modifiers_from_event(const InputEventWithModifiers *event);
Key get_modifiers_mask() const; BitField<KeyModifierMask> get_modifiers_mask() const;
virtual String as_text() const override; virtual String as_text() const override;
virtual String to_string() override; virtual String to_string() override;
@ -195,7 +195,7 @@ public:
class InputEventMouse : public InputEventWithModifiers { class InputEventMouse : public InputEventWithModifiers {
GDCLASS(InputEventMouse, InputEventWithModifiers); GDCLASS(InputEventMouse, InputEventWithModifiers);
MouseButton button_mask = MouseButton::NONE; BitField<MouseButtonMask> button_mask;
Vector2 pos; Vector2 pos;
Vector2 global_pos; Vector2 global_pos;
@ -204,8 +204,8 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
void set_button_mask(MouseButton p_mask); void set_button_mask(BitField<MouseButtonMask> p_mask);
MouseButton get_button_mask() const; BitField<MouseButtonMask> get_button_mask() const;
void set_position(const Vector2 &p_pos); void set_position(const Vector2 &p_pos);
Vector2 get_position() const; Vector2 get_position() const;

View File

@ -33,7 +33,7 @@
#include "core/variant/binder_common.h" #include "core/variant/binder_common.h"
VARIANT_ENUM_CAST(MethodFlags) VARIANT_BITFIELD_CAST(MethodFlags)
// some helpers // some helpers

View File

@ -146,22 +146,53 @@ VARIANT_ENUM_CAST(Side);
VARIANT_ENUM_CAST(ClockDirection); VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner); VARIANT_ENUM_CAST(Corner);
VARIANT_ENUM_CAST(HatDir); VARIANT_ENUM_CAST(HatDir);
VARIANT_ENUM_CAST(HatMask); VARIANT_BITFIELD_CAST(HatMask);
VARIANT_ENUM_CAST(JoyAxis); VARIANT_ENUM_CAST(JoyAxis);
VARIANT_ENUM_CAST(JoyButton); VARIANT_ENUM_CAST(JoyButton);
VARIANT_ENUM_CAST(Key);
VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(MIDIMessage); VARIANT_ENUM_CAST(MIDIMessage);
VARIANT_ENUM_CAST(MouseButton); VARIANT_ENUM_CAST(MouseButton);
VARIANT_BITFIELD_CAST(MouseButtonMask);
VARIANT_ENUM_CAST(Orientation); VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HorizontalAlignment); VARIANT_ENUM_CAST(HorizontalAlignment);
VARIANT_ENUM_CAST(VerticalAlignment); VARIANT_ENUM_CAST(VerticalAlignment);
VARIANT_ENUM_CAST(InlineAlignment); VARIANT_ENUM_CAST(InlineAlignment);
VARIANT_ENUM_CAST(PropertyHint); VARIANT_ENUM_CAST(PropertyHint);
VARIANT_ENUM_CAST(PropertyUsageFlags); VARIANT_BITFIELD_CAST(PropertyUsageFlags);
VARIANT_ENUM_CAST(Variant::Type); VARIANT_ENUM_CAST(Variant::Type);
VARIANT_ENUM_CAST(Variant::Operator); VARIANT_ENUM_CAST(Variant::Operator);
// Key
VARIANT_ENUM_CAST(Key);
VARIANT_BITFIELD_CAST(KeyModifierMask);
static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
return a;
}
static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) {
a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t()));
return a;
}
static inline Key operator|(Key a, BitField<KeyModifierMask> b) {
return (Key)((int)a | (int)b.operator int64_t());
}
static inline Key operator&(Key a, BitField<KeyModifierMask> b) {
return (Key)((int)a & (int)b.operator int64_t());
}
static inline Key operator+(BitField<KeyModifierMask> a, Key b) {
return (Key)((int)a.operator int64_t() + (int)b);
}
static inline Key operator|(BitField<KeyModifierMask> a, Key b) {
return (Key)((int)a.operator int64_t() | (int)b);
}
template <> template <>
struct VariantCaster<char32_t> { struct VariantCaster<char32_t> {
static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) { static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {

View File

@ -287,11 +287,14 @@ class BitField {
int64_t value = 0; int64_t value = 0;
public: public:
_FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; } _FORCE_INLINE_ void set_flag(T p_flag) { value |= (int64_t)p_flag; }
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; } _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & (int64_t)p_flag; }
_FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; } _FORCE_INLINE_ bool is_empty() const { return value == 0; }
_FORCE_INLINE_ void clear_flag(T p_flag) { value &= ~(int64_t)p_flag; }
_FORCE_INLINE_ void clear() { value = 0; }
_FORCE_INLINE_ BitField() = default; _FORCE_INLINE_ BitField() = default;
_FORCE_INLINE_ BitField(int64_t p_value) { value = p_value; } _FORCE_INLINE_ BitField(int64_t p_value) { value = p_value; }
_FORCE_INLINE_ BitField(T p_value) { value = (int64_t)p_value; }
_FORCE_INLINE_ operator int64_t() const { return value; } _FORCE_INLINE_ operator int64_t() const { return value; }
_FORCE_INLINE_ operator Variant() const { return value; } _FORCE_INLINE_ operator Variant() const { return value; }
}; };

View File

@ -2319,31 +2319,31 @@
<constant name="KEY_YDIAERESIS" value="255" enum="Key"> <constant name="KEY_YDIAERESIS" value="255" enum="Key">
ÿ key. ÿ key.
</constant> </constant>
<constant name="KEY_CODE_MASK" value="8388607" enum="KeyModifierMask"> <constant name="KEY_CODE_MASK" value="8388607" enum="KeyModifierMask" is_bitfield="true">
Key Code mask. Key Code mask.
</constant> </constant>
<constant name="KEY_MODIFIER_MASK" value="532676608" enum="KeyModifierMask"> <constant name="KEY_MODIFIER_MASK" value="532676608" enum="KeyModifierMask" is_bitfield="true">
Modifier key mask. Modifier key mask.
</constant> </constant>
<constant name="KEY_MASK_CMD_OR_CTRL" value="16777216" enum="KeyModifierMask"> <constant name="KEY_MASK_CMD_OR_CTRL" value="16777216" enum="KeyModifierMask" is_bitfield="true">
Automatically remapped to [constant KEY_META] on macOS and [constant KEY_CTRL] on other platforms, this mask is never set in the actual events, and should be used for key mapping only. Automatically remapped to [constant KEY_META] on macOS and [constant KEY_CTRL] on other platforms, this mask is never set in the actual events, and should be used for key mapping only.
</constant> </constant>
<constant name="KEY_MASK_SHIFT" value="33554432" enum="KeyModifierMask"> <constant name="KEY_MASK_SHIFT" value="33554432" enum="KeyModifierMask" is_bitfield="true">
Shift key mask. Shift key mask.
</constant> </constant>
<constant name="KEY_MASK_ALT" value="67108864" enum="KeyModifierMask"> <constant name="KEY_MASK_ALT" value="67108864" enum="KeyModifierMask" is_bitfield="true">
Alt or Option (on macOS) key mask. Alt or Option (on macOS) key mask.
</constant> </constant>
<constant name="KEY_MASK_META" value="134217728" enum="KeyModifierMask"> <constant name="KEY_MASK_META" value="134217728" enum="KeyModifierMask" is_bitfield="true">
Command (on macOS) or Meta/Windows key mask. Command (on macOS) or Meta/Windows key mask.
</constant> </constant>
<constant name="KEY_MASK_CTRL" value="268435456" enum="KeyModifierMask"> <constant name="KEY_MASK_CTRL" value="268435456" enum="KeyModifierMask" is_bitfield="true">
Ctrl key mask. Ctrl key mask.
</constant> </constant>
<constant name="KEY_MASK_KPAD" value="536870912" enum="KeyModifierMask"> <constant name="KEY_MASK_KPAD" value="536870912" enum="KeyModifierMask" is_bitfield="true">
Keypad key mask. Keypad key mask.
</constant> </constant>
<constant name="KEY_MASK_GROUP_SWITCH" value="1073741824" enum="KeyModifierMask"> <constant name="KEY_MASK_GROUP_SWITCH" value="1073741824" enum="KeyModifierMask" is_bitfield="true">
Group Switch key mask. Group Switch key mask.
</constant> </constant>
<constant name="MOUSE_BUTTON_NONE" value="0" enum="MouseButton"> <constant name="MOUSE_BUTTON_NONE" value="0" enum="MouseButton">
@ -2376,19 +2376,19 @@
<constant name="MOUSE_BUTTON_XBUTTON2" value="9" enum="MouseButton"> <constant name="MOUSE_BUTTON_XBUTTON2" value="9" enum="MouseButton">
Extra mouse button 2. This is sometimes present, usually to the sides of the mouse. Extra mouse button 2. This is sometimes present, usually to the sides of the mouse.
</constant> </constant>
<constant name="MOUSE_BUTTON_MASK_LEFT" value="1" enum="MouseButton"> <constant name="MOUSE_BUTTON_MASK_LEFT" value="1" enum="MouseButtonMask" is_bitfield="true">
Primary mouse button mask, usually for the left button. Primary mouse button mask, usually for the left button.
</constant> </constant>
<constant name="MOUSE_BUTTON_MASK_RIGHT" value="2" enum="MouseButton"> <constant name="MOUSE_BUTTON_MASK_RIGHT" value="2" enum="MouseButtonMask" is_bitfield="true">
Secondary mouse button mask, usually for the right button. Secondary mouse button mask, usually for the right button.
</constant> </constant>
<constant name="MOUSE_BUTTON_MASK_MIDDLE" value="4" enum="MouseButton"> <constant name="MOUSE_BUTTON_MASK_MIDDLE" value="4" enum="MouseButtonMask" is_bitfield="true">
Middle mouse button mask. Middle mouse button mask.
</constant> </constant>
<constant name="MOUSE_BUTTON_MASK_XBUTTON1" value="128" enum="MouseButton"> <constant name="MOUSE_BUTTON_MASK_MB_XBUTTON1" value="128" enum="MouseButtonMask" is_bitfield="true">
Extra mouse button 1 mask. Extra mouse button 1 mask.
</constant> </constant>
<constant name="MOUSE_BUTTON_MASK_XBUTTON2" value="256" enum="MouseButton"> <constant name="MOUSE_BUTTON_MASK_MB_XBUTTON2" value="256" enum="MouseButtonMask" is_bitfield="true">
Extra mouse button 2 mask. Extra mouse button 2 mask.
</constant> </constant>
<constant name="JOY_BUTTON_INVALID" value="-1" enum="JoyButton"> <constant name="JOY_BUTTON_INVALID" value="-1" enum="JoyButton">
@ -2840,111 +2840,111 @@
</constant> </constant>
<constant name="PROPERTY_HINT_MAX" value="45" enum="PropertyHint"> <constant name="PROPERTY_HINT_MAX" value="45" enum="PropertyHint">
</constant> </constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags" is_bitfield="true">
The property is not stored, and does not display in the editor. This is the default for non-exported properties. The property is not stored, and does not display in the editor. This is the default for non-exported properties.
</constant> </constant>
<constant name="PROPERTY_USAGE_STORAGE" value="2" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_STORAGE" value="2" enum="PropertyUsageFlags" is_bitfield="true">
The property is serialized and saved in the scene file (default). The property is serialized and saved in the scene file (default).
</constant> </constant>
<constant name="PROPERTY_USAGE_EDITOR" value="4" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_EDITOR" value="4" enum="PropertyUsageFlags" is_bitfield="true">
The property is shown in the [EditorInspector] (default). The property is shown in the [EditorInspector] (default).
</constant> </constant>
<constant name="PROPERTY_USAGE_CHECKABLE" value="8" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_CHECKABLE" value="8" enum="PropertyUsageFlags" is_bitfield="true">
The property can be checked in the [EditorInspector]. The property can be checked in the [EditorInspector].
</constant> </constant>
<constant name="PROPERTY_USAGE_CHECKED" value="16" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_CHECKED" value="16" enum="PropertyUsageFlags" is_bitfield="true">
The property is checked in the [EditorInspector]. The property is checked in the [EditorInspector].
</constant> </constant>
<constant name="PROPERTY_USAGE_INTERNATIONALIZED" value="32" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_INTERNATIONALIZED" value="32" enum="PropertyUsageFlags" is_bitfield="true">
The property is a translatable string. The property is a translatable string.
</constant> </constant>
<constant name="PROPERTY_USAGE_GROUP" value="64" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_GROUP" value="64" enum="PropertyUsageFlags" is_bitfield="true">
Used to group properties together in the editor. See [EditorInspector]. Used to group properties together in the editor. See [EditorInspector].
</constant> </constant>
<constant name="PROPERTY_USAGE_CATEGORY" value="128" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_CATEGORY" value="128" enum="PropertyUsageFlags" is_bitfield="true">
Used to categorize properties together in the editor. Used to categorize properties together in the editor.
</constant> </constant>
<constant name="PROPERTY_USAGE_SUBGROUP" value="256" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_SUBGROUP" value="256" enum="PropertyUsageFlags" is_bitfield="true">
Used to group properties together in the editor in a subgroup (under a group). See [EditorInspector]. Used to group properties together in the editor in a subgroup (under a group). See [EditorInspector].
</constant> </constant>
<constant name="PROPERTY_USAGE_CLASS_IS_BITFIELD" value="512" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_CLASS_IS_BITFIELD" value="512" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="1024" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="1024" enum="PropertyUsageFlags" is_bitfield="true">
The property does not save its state in [PackedScene]. The property does not save its state in [PackedScene].
</constant> </constant>
<constant name="PROPERTY_USAGE_RESTART_IF_CHANGED" value="2048" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_RESTART_IF_CHANGED" value="2048" enum="PropertyUsageFlags" is_bitfield="true">
Editing the property prompts the user for restarting the editor. Editing the property prompts the user for restarting the editor.
</constant> </constant>
<constant name="PROPERTY_USAGE_SCRIPT_VARIABLE" value="4096" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_SCRIPT_VARIABLE" value="4096" enum="PropertyUsageFlags" is_bitfield="true">
The property is a script variable which should be serialized and saved in the scene file. The property is a script variable which should be serialized and saved in the scene file.
</constant> </constant>
<constant name="PROPERTY_USAGE_STORE_IF_NULL" value="8192" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_STORE_IF_NULL" value="8192" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED" value="16384" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED" value="16384" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE" value="32768" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE" value="32768" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_CLASS_IS_ENUM" value="65536" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_CLASS_IS_ENUM" value="65536" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_NIL_IS_VARIANT" value="131072" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_NIL_IS_VARIANT" value="131072" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_INTERNAL" value="262144" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_INTERNAL" value="262144" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE" value="524288" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE" value="524288" enum="PropertyUsageFlags" is_bitfield="true">
If the property is a [Resource], a new copy of it is always created when calling [method Node.duplicate] or [method Resource.duplicate]. If the property is a [Resource], a new copy of it is always created when calling [method Node.duplicate] or [method Resource.duplicate].
</constant> </constant>
<constant name="PROPERTY_USAGE_HIGH_END_GFX" value="1048576" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_HIGH_END_GFX" value="1048576" enum="PropertyUsageFlags" is_bitfield="true">
The property is only shown in the editor if modern renderers are supported (GLES3 is excluded). The property is only shown in the editor if modern renderers are supported (GLES3 is excluded).
</constant> </constant>
<constant name="PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT" value="2097152" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT" value="2097152" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT" value="4194304" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT" value="4194304" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_KEYING_INCREMENTS" value="8388608" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_KEYING_INCREMENTS" value="8388608" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_DEFERRED_SET_RESOURCE" value="16777216" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_DEFERRED_SET_RESOURCE" value="16777216" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT" value="33554432" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT" value="33554432" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_EDITOR_BASIC_SETTING" value="67108864" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_EDITOR_BASIC_SETTING" value="67108864" enum="PropertyUsageFlags" is_bitfield="true">
</constant> </constant>
<constant name="PROPERTY_USAGE_READ_ONLY" value="134217728" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_READ_ONLY" value="134217728" enum="PropertyUsageFlags" is_bitfield="true">
The property is read-only in the [EditorInspector]. The property is read-only in the [EditorInspector].
</constant> </constant>
<constant name="PROPERTY_USAGE_ARRAY" value="268435456" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_ARRAY" value="268435456" enum="PropertyUsageFlags" is_bitfield="true">
The property is an array. The property is an array.
</constant> </constant>
<constant name="PROPERTY_USAGE_DEFAULT" value="6" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_DEFAULT" value="6" enum="PropertyUsageFlags" is_bitfield="true">
Default usage (storage, editor and network). Default usage (storage, editor and network).
</constant> </constant>
<constant name="PROPERTY_USAGE_DEFAULT_INTL" value="38" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_DEFAULT_INTL" value="38" enum="PropertyUsageFlags" is_bitfield="true">
Default usage for translatable strings (storage, editor, network and internationalized). Default usage for translatable strings (storage, editor, network and internationalized).
</constant> </constant>
<constant name="PROPERTY_USAGE_NO_EDITOR" value="2" enum="PropertyUsageFlags"> <constant name="PROPERTY_USAGE_NO_EDITOR" value="2" enum="PropertyUsageFlags" is_bitfield="true">
Default usage but without showing the property in the editor (storage, network). Default usage but without showing the property in the editor (storage, network).
</constant> </constant>
<constant name="METHOD_FLAG_NORMAL" value="1" enum="MethodFlags"> <constant name="METHOD_FLAG_NORMAL" value="1" enum="MethodFlags" is_bitfield="true">
Flag for a normal method. Flag for a normal method.
</constant> </constant>
<constant name="METHOD_FLAG_EDITOR" value="2" enum="MethodFlags"> <constant name="METHOD_FLAG_EDITOR" value="2" enum="MethodFlags" is_bitfield="true">
Flag for an editor method. Flag for an editor method.
</constant> </constant>
<constant name="METHOD_FLAG_CONST" value="4" enum="MethodFlags"> <constant name="METHOD_FLAG_CONST" value="4" enum="MethodFlags" is_bitfield="true">
Flag for a constant method. Flag for a constant method.
</constant> </constant>
<constant name="METHOD_FLAG_VIRTUAL" value="8" enum="MethodFlags"> <constant name="METHOD_FLAG_VIRTUAL" value="8" enum="MethodFlags" is_bitfield="true">
Flag for a virtual method. Flag for a virtual method.
</constant> </constant>
<constant name="METHOD_FLAG_VARARG" value="16" enum="MethodFlags"> <constant name="METHOD_FLAG_VARARG" value="16" enum="MethodFlags" is_bitfield="true">
Flag for a method with a variable number of arguments. Flag for a method with a variable number of arguments.
</constant> </constant>
<constant name="METHOD_FLAG_STATIC" value="32" enum="MethodFlags"> <constant name="METHOD_FLAG_STATIC" value="32" enum="MethodFlags" is_bitfield="true">
Flag for a static method. Flag for a static method.
</constant> </constant>
<constant name="METHOD_FLAG_OBJECT_CORE" value="64" enum="MethodFlags"> <constant name="METHOD_FLAG_OBJECT_CORE" value="64" enum="MethodFlags" is_bitfield="true">
Used internally. Allows to not dump core virtual methods (such as [method Object._notification]) to the JSON API. Used internally. Allows to not dump core virtual methods (such as [method Object._notification]) to the JSON API.
</constant> </constant>
<constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags"> <constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags" is_bitfield="true">
Default method flags (normal). Default method flags (normal).
</constant> </constant>
<constant name="TYPE_NIL" value="0" enum="Variant.Type"> <constant name="TYPE_NIL" value="0" enum="Variant.Type">

View File

@ -50,7 +50,7 @@
<member name="button_group" type="ButtonGroup" setter="set_button_group" getter="get_button_group"> <member name="button_group" type="ButtonGroup" setter="set_button_group" getter="get_button_group">
The [ButtonGroup] associated with the button. Not to be confused with node groups. The [ButtonGroup] associated with the button. Not to be confused with node groups.
</member> </member>
<member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButton" default="1"> <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" default="0">
Binary mask to choose which mouse buttons this button will respond to. Binary mask to choose which mouse buttons this button will respond to.
To allow both left-click and right-click, use [code]MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT[/code]. To allow both left-click and right-click, use [code]MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT[/code].
</member> </member>

View File

@ -785,7 +785,7 @@
</description> </description>
</method> </method>
<method name="mouse_get_button_state" qualifiers="const"> <method name="mouse_get_button_state" qualifiers="const">
<return type="int" enum="MouseButton" /> <return type="int" enum="MouseButtonMask" />
<description> <description>
Returns the current state of mouse buttons (whether each button is pressed) as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method Input.get_mouse_button_mask]. Returns the current state of mouse buttons (whether each button is pressed) as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method Input.get_mouse_button_mask].
</description> </description>

View File

@ -155,7 +155,7 @@
</description> </description>
</method> </method>
<method name="get_mouse_button_mask" qualifiers="const"> <method name="get_mouse_button_mask" qualifiers="const">
<return type="int" enum="MouseButton" /> <return type="int" enum="MouseButtonMask" />
<description> <description>
Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method DisplayServer.mouse_get_button_state]. Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method DisplayServer.mouse_get_button_state].
</description> </description>

View File

@ -10,7 +10,7 @@
<link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link> <link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials> </tutorials>
<members> <members>
<member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButton" default="0"> <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" default="0">
The mouse button mask identifier, one of or a bitwise combination of the [enum MouseButton] button masks. The mouse button mask identifier, one of or a bitwise combination of the [enum MouseButton] button masks.
</member> </member>
<member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" default="Vector2(0, 0)"> <member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" default="Vector2(0, 0)">

View File

@ -2919,7 +2919,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
} }
} }
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && moving_selection_attempt) { if (mm.is_valid() && mm->get_button_mask().has_flag(MouseButtonMask::LEFT) && moving_selection_attempt) {
if (!moving_selection) { if (!moving_selection) {
moving_selection = true; moving_selection = true;
emit_signal(SNAME("move_selection_begin")); emit_signal(SNAME("move_selection_begin"));
@ -5309,7 +5309,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && box_selecting) { if (mm.is_valid() && box_selecting) {
if ((mm->get_button_mask() & MouseButton::MASK_LEFT) == MouseButton::NONE) { if (!mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
// No longer. // No longer.
box_selection->hide(); box_selection->hide();
box_selecting = false; box_selecting = false;

View File

@ -468,7 +468,7 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
x = frame_metrics.size() - 1; x = frame_metrics.size() - 1;
} }
if (mb.is_valid() || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mb.is_valid() || (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
updating_frame = true; updating_frame = true;
if (x < total_metrics) { if (x < total_metrics) {

View File

@ -544,7 +544,7 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
hover_metric = -1; hover_metric = -1;
} }
if (mb.is_valid() || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mb.is_valid() || mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
//cursor_metric=x; //cursor_metric=x;
updating_frame = true; updating_frame = true;

View File

@ -845,6 +845,7 @@ void DocTools::generate(bool p_basic_types) {
for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) {
DocData::ConstantDoc cd; DocData::ConstantDoc cd;
cd.name = CoreConstants::get_global_constant_name(i); cd.name = CoreConstants::get_global_constant_name(i);
cd.is_bitfield = CoreConstants::is_global_constant_bitfield(i);
if (!CoreConstants::get_ignore_value_in_docs(i)) { if (!CoreConstants::get_ignore_value_in_docs(i)) {
cd.value = itos(CoreConstants::get_global_constant_value(i)); cd.value = itos(CoreConstants::get_global_constant_value(i));
cd.is_value_valid = true; cd.is_value_valid = true;

View File

@ -618,7 +618,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
if (is_layout_rtl()) { if (is_layout_rtl()) {
mpos.x = get_size().x - mpos.x; mpos.x = get_size().x - mpos.x;
} }
bool button_left = (me->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE; bool button_left = me->get_button_mask().has_flag(MouseButtonMask::LEFT);
bool new_keying_hover = keying_rect.has_point(mpos) && !button_left; bool new_keying_hover = keying_rect.has_point(mpos) && !button_left;
if (new_keying_hover != keying_hover) { if (new_keying_hover != keying_hover) {

View File

@ -1577,7 +1577,7 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
const Ref<InputEventMouseMotion> mm = p_ev; const Ref<InputEventMouseMotion> mm = p_ev;
if (dragging && mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (dragging && mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
float rel = mm->get_relative().x; float rel = mm->get_relative().x;
if (rel == 0) { if (rel == 0) {
return; return;

View File

@ -37,7 +37,7 @@ void EditorTitleBar::input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && moving) { if (mm.is_valid() && moving) {
if ((mm->get_button_mask() & MouseButton::LEFT) == MouseButton::LEFT) { if (mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
Window *w = Object::cast_to<Window>(get_viewport()); Window *w = Object::cast_to<Window>(get_viewport());
if (w) { if (w) {
Point2 mouse = DisplayServer::get_singleton()->mouse_get_position(); Point2 mouse = DisplayServer::get_singleton()->mouse_get_position();

View File

@ -849,7 +849,7 @@ void SceneImportSettings::_viewport_input(const Ref<InputEvent> &p_input) {
zoom = &md.cam_zoom; zoom = &md.cam_zoom;
} }
Ref<InputEventMouseMotion> mm = p_input; Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
(*rot_x) -= mm->get_relative().y * 0.01 * EDSCALE; (*rot_x) -= mm->get_relative().y * 0.01 * EDSCALE;
(*rot_y) -= mm->get_relative().x * 0.01 * EDSCALE; (*rot_y) -= mm->get_relative().x * 0.01 * EDSCALE;
(*rot_x) = CLAMP((*rot_x), -Math_PI / 2, Math_PI / 2); (*rot_x) = CLAMP((*rot_x), -Math_PI / 2, Math_PI / 2);

View File

@ -410,7 +410,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
if (mm.is_valid()) { if (mm.is_valid()) {
Vector2 gpoint = mm->get_position(); Vector2 gpoint = mm->get_position();
if (edited_point.valid() && (wip_active || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE)) { if (edited_point.valid() && (wip_active || mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
Vector2 cpoint = _get_node()->to_local(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint))); Vector2 cpoint = _get_node()->to_local(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
//Move the point in a single axis. Should only work when editing a polygon and while holding shift. //Move the point in a single axis. Should only work when editing a polygon and while holding shift.

View File

@ -200,7 +200,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
_update_edited_point_pos(); _update_edited_point_pos();
} }
if (mm.is_valid() && tool_blend->is_pressed() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && tool_blend->is_pressed() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
float blend_pos = mm->get_position().x / blend_space_draw->get_size().x; float blend_pos = mm->get_position().x / blend_space_draw->get_size().x;
blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos *= blend_space->get_max_space() - blend_space->get_min_space();
blend_pos += blend_space->get_min_space(); blend_pos += blend_space->get_min_space();

View File

@ -308,7 +308,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
blend_space_draw->queue_redraw(); blend_space_draw->queue_redraw();
} }
if (mm.is_valid() && tool_blend->is_pressed() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && tool_blend->is_pressed() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
Vector2 blend_pos = (mm->get_position() / blend_space_draw->get_size()); Vector2 blend_pos = (mm->get_position() / blend_space_draw->get_size());
blend_pos.y = 1.0 - blend_pos.y; blend_pos.y = 1.0 - blend_pos.y;
blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space());

View File

@ -337,7 +337,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
// Pan window // Pan window
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { if (mm.is_valid() && mm->get_button_mask().has_flag(MouseButtonMask::MIDDLE)) {
h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
} }

View File

@ -1322,7 +1322,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
// Drag the pivot (in pivot mode / with V key) // Drag the pivot (in pivot mode / with V key)
if (drag_type == DRAG_NONE) { if (drag_type == DRAG_NONE) {
if ((b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::LEFT && tool == TOOL_EDIT_PIVOT) || if ((b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::LEFT && tool == TOOL_EDIT_PIVOT) ||
(k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::V && tool == TOOL_SELECT && k->get_modifiers_mask() == Key::NONE)) { (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::V && tool == TOOL_SELECT && k->get_modifiers_mask().is_empty())) {
List<CanvasItem *> selection = _get_edited_canvas_items(); List<CanvasItem *> selection = _get_edited_canvas_items();
// Filters the selection with nodes that allow setting the pivot // Filters the selection with nodes that allow setting the pivot

View File

@ -44,7 +44,7 @@ void MaterialEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null()); ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
rot.x -= mm->get_relative().y * 0.01; rot.x -= mm->get_relative().y * 0.01;
rot.y -= mm->get_relative().x * 0.01; rot.y -= mm->get_relative().x * 0.01;

View File

@ -39,7 +39,7 @@ void MeshEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null()); ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
rot_x -= mm->get_relative().y * 0.01; rot_x -= mm->get_relative().y * 0.01;
rot_y -= mm->get_relative().x * 0.01; rot_y -= mm->get_relative().x * 0.01;
if (rot_x < -Math_PI / 2) { if (rot_x < -Math_PI / 2) {

View File

@ -1911,7 +1911,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} }
} }
if (spatial_editor->get_current_hover_gizmo().is_null() && (m->get_button_mask() & MouseButton::MASK_LEFT) == MouseButton::NONE && !_edit.gizmo.is_valid()) { if (spatial_editor->get_current_hover_gizmo().is_null() && !m->get_button_mask().has_flag(MouseButtonMask::LEFT) && !_edit.gizmo.is_valid()) {
_transform_gizmo_select(_edit.mouse_pos, true); _transform_gizmo_select(_edit.mouse_pos, true);
} }
@ -1924,7 +1924,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary); String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary);
set_message(n + ": " + String(v)); set_message(n + ": " + String(v));
} else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE || _edit.instant) { } else if (m->get_button_mask().has_flag(MouseButtonMask::LEFT) || _edit.instant) {
if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) {
nav_mode = NAVIGATION_ORBIT; nav_mode = NAVIGATION_ORBIT;
} else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_shift_pressed()) { } else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_shift_pressed()) {
@ -1963,7 +1963,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
update_transform(m->get_position(), _get_key_modifier(m) == Key::SHIFT); update_transform(m->get_position(), _get_key_modifier(m) == Key::SHIFT);
} }
} else if ((m->get_button_mask() & MouseButton::MASK_RIGHT) != MouseButton::NONE || freelook_active) { } else if (m->get_button_mask().has_flag(MouseButtonMask::RIGHT) || freelook_active) {
if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) {
nav_mode = NAVIGATION_ZOOM; nav_mode = NAVIGATION_ZOOM;
} else if (freelook_active) { } else if (freelook_active) {
@ -1972,7 +1972,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_PAN; nav_mode = NAVIGATION_PAN;
} }
} else if ((m->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { } else if (m->get_button_mask().has_flag(MouseButtonMask::MIDDLE)) {
const Key mod = _get_key_modifier(m); const Key mod = _get_key_modifier(m);
if (nav_scheme == NAVIGATION_GODOT) { if (nav_scheme == NAVIGATION_GODOT) {
if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) { if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) {
@ -7995,7 +7995,7 @@ void Node3DEditor::_update_preview_environment() {
void Node3DEditor::_sun_direction_input(const Ref<InputEvent> &p_event) { void Node3DEditor::_sun_direction_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
sun_rotation.x += mm->get_relative().y * (0.02 * EDSCALE); sun_rotation.x += mm->get_relative().y * (0.02 * EDSCALE);
sun_rotation.y -= mm->get_relative().x * (0.02 * EDSCALE); sun_rotation.y -= mm->get_relative().x * (0.02 * EDSCALE);
sun_rotation.x = CLAMP(sun_rotation.x, -Math_TAU / 4, Math_TAU / 4); sun_rotation.x = CLAMP(sun_rotation.x, -Math_TAU / 4, Math_TAU / 4);

View File

@ -313,7 +313,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) { if (mm.is_valid()) {
if (edited_point != -1 && (wip_active || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE)) { if (edited_point != -1 && (wip_active || mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
Vector2 gpoint = mm->get_position(); Vector2 gpoint = mm->get_position();
Vector3 ray_from = p_camera->project_ray_origin(gpoint); Vector3 ray_from = p_camera->project_ray_origin(gpoint);

View File

@ -197,7 +197,7 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
} }
const Ref<InputEventMouseMotion> mm = p_event; const Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
// Select by holding down the mouse button on frames. // Select by holding down the mouse button on frames.
const int idx = _sheet_preview_position_to_frame_index(mm->get_position()); const int idx = _sheet_preview_position_to_frame_index(mm->get_position());
@ -238,7 +238,7 @@ void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) {
} }
const Ref<InputEventMouseMotion> mm = p_event; const Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE) { if (mm.is_valid() && mm->get_button_mask().has_flag(MouseButtonMask::MIDDLE)) {
const Vector2 dragged = Input::get_singleton()->warp_mouse_motion(mm, split_sheet_scroll->get_global_rect()); const Vector2 dragged = Input::get_singleton()->warp_mouse_motion(mm, split_sheet_scroll->get_global_rect());
split_sheet_scroll->set_h_scroll(split_sheet_scroll->get_h_scroll() - dragged.x); split_sheet_scroll->set_h_scroll(split_sheet_scroll->get_h_scroll() - dragged.x);
split_sheet_scroll->set_v_scroll(split_sheet_scroll->get_v_scroll() - dragged.y); split_sheet_scroll->set_v_scroll(split_sheet_scroll->get_v_scroll() - dragged.y);

View File

@ -36,7 +36,7 @@ void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null()); ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
y_rot += -mm->get_relative().x * 0.01; y_rot += -mm->get_relative().x * 0.01;
x_rot += mm->get_relative().y * 0.01; x_rot += mm->get_relative().y * 0.01;
_update_material(); _update_material();

View File

@ -225,7 +225,7 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const
} }
} }
void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) { void AndroidInputHandler::_parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) {
if (!mouse_event_info.valid) { if (!mouse_event_info.valid) {
return; return;
} }
@ -242,7 +242,7 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask
hover_prev_pos = mouse_event_info.pos; hover_prev_pos = mouse_event_info.pos;
} }
ev->set_pressed(p_pressed); ev->set_pressed(p_pressed);
MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask); BitField<MouseButtonMask> changed_button_mask = BitField<MouseButtonMask>(buttons_state.operator int64_t() ^ event_buttons_mask.operator int64_t());
buttons_state = event_buttons_mask; buttons_state = event_buttons_mask;
@ -253,12 +253,12 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask
} }
void AndroidInputHandler::_release_mouse_event_info(bool p_source_mouse_relative) { void AndroidInputHandler::_release_mouse_event_info(bool p_source_mouse_relative) {
_parse_mouse_event_info(MouseButton::NONE, false, false, p_source_mouse_relative); _parse_mouse_event_info(BitField<MouseButtonMask>(), false, false, p_source_mouse_relative);
mouse_event_info.valid = false; mouse_event_info.valid = false;
} }
void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative) { void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative) {
MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask); BitField<MouseButtonMask> event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask);
switch (p_event_action) { switch (p_event_action) {
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter
@ -342,11 +342,11 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an
} }
} }
void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) {
Ref<InputEventMouseButton> evd = ev->duplicate(); Ref<InputEventMouseButton> evd = ev->duplicate();
_set_key_modifier_state(evd); _set_key_modifier_state(evd);
evd->set_button_index(wheel_button); evd->set_button_index(wheel_button);
evd->set_button_mask(MouseButton(event_buttons_mask ^ mouse_button_to_mask(wheel_button))); evd->set_button_mask(BitField<MouseButtonMask>(event_buttons_mask.operator int64_t() ^ int64_t(mouse_button_to_mask(wheel_button))));
evd->set_factor(factor); evd->set_factor(factor);
Input::get_singleton()->parse_input_event(evd); Input::get_singleton()->parse_input_event(evd);
Ref<InputEventMouseButton> evdd = evd->duplicate(); Ref<InputEventMouseButton> evdd = evd->duplicate();
@ -373,39 +373,39 @@ void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) {
Input::get_singleton()->parse_input_event(pan_event); Input::get_singleton()->parse_input_event(pan_event);
} }
MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) { MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) {
switch (button_mask) { switch (MouseButtonMask(button_mask.operator int64_t())) {
case MouseButton::MASK_LEFT: case MouseButtonMask::LEFT:
return MouseButton::LEFT; return MouseButton::LEFT;
case MouseButton::MASK_RIGHT: case MouseButtonMask::RIGHT:
return MouseButton::RIGHT; return MouseButton::RIGHT;
case MouseButton::MASK_MIDDLE: case MouseButtonMask::MIDDLE:
return MouseButton::MIDDLE; return MouseButton::MIDDLE;
case MouseButton::MASK_XBUTTON1: case MouseButtonMask::MB_XBUTTON1:
return MouseButton::MB_XBUTTON1; return MouseButton::MB_XBUTTON1;
case MouseButton::MASK_XBUTTON2: case MouseButtonMask::MB_XBUTTON2:
return MouseButton::MB_XBUTTON2; return MouseButton::MB_XBUTTON2;
default: default:
return MouseButton::NONE; return MouseButton::NONE;
} }
} }
MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) { BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
MouseButton godot_button_mask = MouseButton::NONE; BitField<MouseButtonMask> godot_button_mask;
if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) { if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
godot_button_mask |= MouseButton::MASK_LEFT; godot_button_mask.set_flag(MouseButtonMask::LEFT);
} }
if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) {
godot_button_mask |= MouseButton::MASK_RIGHT; godot_button_mask.set_flag(MouseButtonMask::RIGHT);
} }
if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) { if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) {
godot_button_mask |= MouseButton::MASK_MIDDLE; godot_button_mask.set_flag(MouseButtonMask::MIDDLE);
} }
if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) { if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) {
godot_button_mask |= MouseButton::MASK_XBUTTON1; godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON1);
} }
if (android_button_mask & AMOTION_EVENT_BUTTON_FORWARD) { if (android_button_mask & AMOTION_EVENT_BUTTON_FORWARD) {
godot_button_mask |= MouseButton::MASK_XBUTTON2; godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON2);
} }
return godot_button_mask; return godot_button_mask;

View File

@ -61,7 +61,7 @@ public:
int index = 0; // Can be either JoyAxis or JoyButton. int index = 0; // Can be either JoyAxis or JoyButton.
bool pressed = false; bool pressed = false;
float value = 0; float value = 0;
HatMask hat = HatMask::CENTER; BitField<HatMask> hat;
}; };
private: private:
@ -70,7 +70,7 @@ private:
bool control_mem = false; bool control_mem = false;
bool meta_mem = false; bool meta_mem = false;
MouseButton buttons_state = MouseButton::NONE; BitField<MouseButtonMask> buttons_state;
Vector<TouchPos> touch; Vector<TouchPos> touch;
MouseEventInfo mouse_event_info; MouseEventInfo mouse_event_info;
@ -78,12 +78,12 @@ private:
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev); void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
static MouseButton _button_index_from_mask(MouseButton button_mask); static MouseButton _button_index_from_mask(BitField<MouseButtonMask> button_mask);
static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask); static BitField<MouseButtonMask> _android_button_mask_to_godot_button_mask(int android_button_mask);
void _wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor); void _wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor);
void _parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative); void _parse_mouse_event_info(BitField<MouseButtonMask> event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative);
void _release_mouse_event_info(bool p_source_mouse_relative = false); void _release_mouse_event_info(bool p_source_mouse_relative = false);

View File

@ -624,8 +624,8 @@ Point2i DisplayServerAndroid::mouse_get_position() const {
return Input::get_singleton()->get_mouse_position(); return Input::get_singleton()->get_mouse_position();
} }
MouseButton DisplayServerAndroid::mouse_get_button_state() const { BitField<MouseButtonMask> DisplayServerAndroid::mouse_get_button_state() const {
return (MouseButton)Input::get_singleton()->get_mouse_button_mask(); return Input::get_singleton()->get_mouse_button_mask();
} }
void DisplayServerAndroid::_cursor_set_shape_helper(CursorShape p_shape, bool force) { void DisplayServerAndroid::_cursor_set_shape_helper(CursorShape p_shape, bool force) {

View File

@ -207,7 +207,7 @@ public:
void notify_surface_changed(int p_width, int p_height); void notify_surface_changed(int p_width, int p_height);
virtual Point2i mouse_get_position() const override; virtual Point2i mouse_get_position() const override;
virtual MouseButton mouse_get_button_state() const override; virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
void reset_swap_buffers_flag(); void reset_swap_buffers_flag();
bool should_swap_buffers() const; bool should_swap_buffers() const;

View File

@ -353,19 +353,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
AndroidInputHandler::JoypadEvent jevent; AndroidInputHandler::JoypadEvent jevent;
jevent.device = p_device; jevent.device = p_device;
jevent.type = AndroidInputHandler::JOY_EVENT_HAT; jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
HatMask hat = HatMask::CENTER; BitField<HatMask> hat;
if (p_hat_x != 0) { if (p_hat_x != 0) {
if (p_hat_x < 0) { if (p_hat_x < 0) {
hat |= HatMask::LEFT; hat.set_flag(HatMask::LEFT);
} else { } else {
hat |= HatMask::RIGHT; hat.set_flag(HatMask::RIGHT);
} }
} }
if (p_hat_y != 0) { if (p_hat_y != 0) {
if (p_hat_y < 0) { if (p_hat_y < 0) {
hat |= HatMask::UP; hat.set_flag(HatMask::UP);
} else { } else {
hat |= HatMask::DOWN; hat.set_flag(HatMask::DOWN);
} }
} }
jevent.hat = hat; jevent.hat = hat;

View File

@ -59,7 +59,7 @@ JoypadLinux::Joypad::~Joypad() {
} }
void JoypadLinux::Joypad::reset() { void JoypadLinux::Joypad::reset() {
dpad = HatMask::CENTER; dpad = 0;
fd = -1; fd = -1;
for (int i = 0; i < MAX_ABS; i++) { for (int i = 0; i < MAX_ABS; i++) {
abs_map[i] = -1; abs_map[i] = -1;
@ -485,27 +485,33 @@ void JoypadLinux::process_joypads() {
case ABS_HAT0X: case ABS_HAT0X:
if (joypad_event.value != 0) { if (joypad_event.value != 0) {
if (joypad_event.value < 0) { if (joypad_event.value < 0) {
joypad.dpad = (HatMask)((joypad.dpad | HatMask::LEFT) & ~HatMask::RIGHT); joypad.dpad.set_flag(HatMask::LEFT);
joypad.dpad.clear_flag(HatMask::RIGHT);
} else { } else {
joypad.dpad = (HatMask)((joypad.dpad | HatMask::RIGHT) & ~HatMask::LEFT); joypad.dpad.set_flag(HatMask::RIGHT);
joypad.dpad.clear_flag(HatMask::LEFT);
} }
} else { } else {
joypad.dpad &= ~(HatMask::LEFT | HatMask::RIGHT); joypad.dpad.clear_flag(HatMask::LEFT);
joypad.dpad.clear_flag(HatMask::RIGHT);
} }
input->joy_hat(i, (HatMask)joypad.dpad); input->joy_hat(i, joypad.dpad);
break; break;
case ABS_HAT0Y: case ABS_HAT0Y:
if (joypad_event.value != 0) { if (joypad_event.value != 0) {
if (joypad_event.value < 0) { if (joypad_event.value < 0) {
joypad.dpad = (HatMask)((joypad.dpad | HatMask::UP) & ~HatMask::DOWN); joypad.dpad.set_flag(HatMask::UP);
joypad.dpad.clear_flag(HatMask::DOWN);
} else { } else {
joypad.dpad = (HatMask)((joypad.dpad | HatMask::DOWN) & ~HatMask::UP); joypad.dpad.set_flag(HatMask::DOWN);
joypad.dpad.clear_flag(HatMask::UP);
} }
} else { } else {
joypad.dpad &= ~(HatMask::UP | HatMask::DOWN); joypad.dpad.clear_flag(HatMask::UP);
joypad.dpad.clear_flag(HatMask::DOWN);
} }
input->joy_hat(i, (HatMask)joypad.dpad); input->joy_hat(i, joypad.dpad);
break; break;
default: default:

View File

@ -62,7 +62,7 @@ private:
float curr_axis[MAX_ABS]; float curr_axis[MAX_ABS];
int key_map[MAX_KEY]; int key_map[MAX_KEY];
int abs_map[MAX_ABS]; int abs_map[MAX_ABS];
HatMask dpad = HatMask::CENTER; BitField<HatMask> dpad;
int fd = -1; int fd = -1;
String devpath; String devpath;

View File

@ -458,7 +458,7 @@ Point2i DisplayServerX11::mouse_get_position() const {
return Vector2i(); return Vector2i();
} }
MouseButton DisplayServerX11::mouse_get_button_state() const { BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
return last_button_state; return last_button_state;
} }
@ -2843,13 +2843,13 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp
state->set_meta_pressed((p_x11_state & Mod4Mask)); state->set_meta_pressed((p_x11_state & Mod4Mask));
} }
MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) { BitField<MouseButtonMask> DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
MouseButton mask = mouse_button_to_mask(p_x11_button); MouseButtonMask mask = mouse_button_to_mask(p_x11_button);
if (p_x11_type == ButtonPress) { if (p_x11_type == ButtonPress) {
last_button_state |= mask; last_button_state.set_flag(mask);
} else { } else {
last_button_state &= ~mask; last_button_state.clear_flag(mask);
} }
return last_button_state; return last_button_state;
@ -4171,13 +4171,13 @@ void DisplayServerX11::process_events() {
if (xi.pressure_supported) { if (xi.pressure_supported) {
mm->set_pressure(xi.pressure); mm->set_pressure(xi.pressure);
} else { } else {
mm->set_pressure(bool(mouse_get_button_state() & MouseButton::MASK_LEFT) ? 1.0f : 0.0f); mm->set_pressure(bool(mouse_get_button_state().has_flag(MouseButtonMask::LEFT)) ? 1.0f : 0.0f);
} }
mm->set_tilt(xi.tilt); mm->set_tilt(xi.tilt);
mm->set_pen_inverted(xi.pen_inverted); mm->set_pen_inverted(xi.pen_inverted);
_get_key_modifier_state(event.xmotion.state, mm); _get_key_modifier_state(event.xmotion.state, mm);
mm->set_button_mask((MouseButton)mouse_get_button_state()); mm->set_button_mask(mouse_get_button_state());
mm->set_position(pos); mm->set_position(pos);
mm->set_global_position(pos); mm->set_global_position(pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity()); mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());

View File

@ -205,7 +205,7 @@ class DisplayServerX11 : public DisplayServer {
Point2i last_click_pos = Point2i(-100, -100); Point2i last_click_pos = Point2i(-100, -100);
uint64_t last_click_ms = 0; uint64_t last_click_ms = 0;
MouseButton last_click_button_index = MouseButton::NONE; MouseButton last_click_button_index = MouseButton::NONE;
MouseButton last_button_state = MouseButton::NONE; BitField<MouseButtonMask> last_button_state;
bool app_focused = false; bool app_focused = false;
uint64_t time_since_no_focus = 0; uint64_t time_since_no_focus = 0;
@ -234,7 +234,7 @@ class DisplayServerX11 : public DisplayServer {
Rect2i _screen_get_rect(int p_screen) const; Rect2i _screen_get_rect(int p_screen) const;
MouseButton _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type); BitField<MouseButtonMask> _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type);
void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
void _flush_mouse_motion(); void _flush_mouse_motion();
@ -344,7 +344,7 @@ public:
virtual void warp_mouse(const Point2i &p_position) override; virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override; virtual Point2i mouse_get_position() const override;
virtual MouseButton mouse_get_button_state() const override; virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override; virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override; virtual String clipboard_get() const override;

View File

@ -154,7 +154,7 @@ private:
CGEventSourceRef event_source; CGEventSourceRef event_source;
MouseMode mouse_mode = MOUSE_MODE_VISIBLE; MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
MouseButton last_button_state = MouseButton::NONE; BitField<MouseButtonMask> last_button_state;
bool drop_events = false; bool drop_events = false;
bool in_dispatch_input_event = false; bool in_dispatch_input_event = false;
@ -317,8 +317,8 @@ public:
bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp); bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp);
virtual void warp_mouse(const Point2i &p_position) override; virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override; virtual Point2i mouse_get_position() const override;
void mouse_set_button_state(MouseButton p_state); void mouse_set_button_state(BitField<MouseButtonMask> p_state);
virtual MouseButton mouse_get_button_state() const override; virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override; virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override; virtual String clipboard_get() const override;

View File

@ -2034,11 +2034,11 @@ Point2i DisplayServerMacOS::mouse_get_position() const {
return Vector2i(); return Vector2i();
} }
void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) { void DisplayServerMacOS::mouse_set_button_state(BitField<MouseButtonMask> p_state) {
last_button_state = p_state; last_button_state = p_state;
} }
MouseButton DisplayServerMacOS::mouse_get_button_state() const { BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const {
return last_button_state; return last_button_state;
} }

View File

@ -66,7 +66,7 @@
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor; - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy; - (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy;
- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed; - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed;
- (void)setWindowID:(DisplayServer::WindowID)wid; - (void)setWindowID:(DisplayServer::WindowID)wid;
- (void)updateLayerDelegate; - (void)updateLayerDelegate;
- (void)cancelComposition; - (void)cancelComposition;

View File

@ -371,19 +371,21 @@
ds->cursor_update_shape(); ds->cursor_update_shape();
} }
- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed { - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index pressed:(bool)pressed {
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (!ds || !ds->has_window(window_id)) { if (!ds || !ds->has_window(window_id)) {
return; return;
} }
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton last_button_state = ds->mouse_get_button_state(); BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state();
MouseButtonMask mask = mouse_button_to_mask(index);
if (pressed) { if (pressed) {
last_button_state |= mask; last_button_state.set_flag(mask);
} else { } else {
last_button_state &= (MouseButton)~mask; last_button_state.clear_flag(mask);
} }
ds->mouse_set_button_state(last_button_state); ds->mouse_set_button_state(last_button_state);
@ -407,10 +409,10 @@
- (void)mouseDown:(NSEvent *)event { - (void)mouseDown:(NSEvent *)event {
if (([event modifierFlags] & NSEventModifierFlagControl)) { if (([event modifierFlags] & NSEventModifierFlagControl)) {
mouse_down_control = true; mouse_down_control = true;
[self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; [self processMouseEvent:event index:MouseButton::RIGHT pressed:true];
} else { } else {
mouse_down_control = false; mouse_down_control = false;
[self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:true]; [self processMouseEvent:event index:MouseButton::LEFT pressed:true];
} }
} }
@ -420,9 +422,9 @@
- (void)mouseUp:(NSEvent *)event { - (void)mouseUp:(NSEvent *)event {
if (mouse_down_control) { if (mouse_down_control) {
[self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; [self processMouseEvent:event index:MouseButton::RIGHT pressed:false];
} else { } else {
[self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:false]; [self processMouseEvent:event index:MouseButton::LEFT pressed:false];
} }
} }
@ -469,7 +471,7 @@
} }
- (void)rightMouseDown:(NSEvent *)event { - (void)rightMouseDown:(NSEvent *)event {
[self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; [self processMouseEvent:event index:MouseButton::RIGHT pressed:true];
} }
- (void)rightMouseDragged:(NSEvent *)event { - (void)rightMouseDragged:(NSEvent *)event {
@ -477,16 +479,16 @@
} }
- (void)rightMouseUp:(NSEvent *)event { - (void)rightMouseUp:(NSEvent *)event {
[self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; [self processMouseEvent:event index:MouseButton::RIGHT pressed:false];
} }
- (void)otherMouseDown:(NSEvent *)event { - (void)otherMouseDown:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) { if ((int)[event buttonNumber] == 2) {
[self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:true]; [self processMouseEvent:event index:MouseButton::MIDDLE pressed:true];
} else if ((int)[event buttonNumber] == 3) { } else if ((int)[event buttonNumber] == 3) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:true]; [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:true];
} else if ((int)[event buttonNumber] == 4) { } else if ((int)[event buttonNumber] == 4) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:true]; [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:true];
} else { } else {
return; return;
} }
@ -498,11 +500,11 @@
- (void)otherMouseUp:(NSEvent *)event { - (void)otherMouseUp:(NSEvent *)event {
if ((int)[event buttonNumber] == 2) { if ((int)[event buttonNumber] == 2) {
[self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:false]; [self processMouseEvent:event index:MouseButton::MIDDLE pressed:false];
} else if ((int)[event buttonNumber] == 3) { } else if ((int)[event buttonNumber] == 3) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:false]; [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 pressed:false];
} else if ((int)[event buttonNumber] == 4) { } else if ((int)[event buttonNumber] == 4) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:false]; [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:false];
} else { } else {
return; return;
} }
@ -751,7 +753,8 @@
} }
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
MouseButton mask = mouse_button_to_mask(button); MouseButtonMask mask = mouse_button_to_mask(button);
BitField<MouseButtonMask> last_button_state = ds->mouse_get_button_state();
Ref<InputEventMouseButton> sc; Ref<InputEventMouseButton> sc;
sc.instantiate(); sc.instantiate();
@ -763,7 +766,7 @@
sc->set_pressed(true); sc->set_pressed(true);
sc->set_position(wd.mouse_pos); sc->set_position(wd.mouse_pos);
sc->set_global_position(wd.mouse_pos); sc->set_global_position(wd.mouse_pos);
MouseButton last_button_state = ds->mouse_get_button_state() | (MouseButton)mask; last_button_state.set_flag(mask);
sc->set_button_mask(last_button_state); sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state); ds->mouse_set_button_state(last_button_state);
@ -776,7 +779,7 @@
sc->set_pressed(false); sc->set_pressed(false);
sc->set_position(wd.mouse_pos); sc->set_position(wd.mouse_pos);
sc->set_global_position(wd.mouse_pos); sc->set_global_position(wd.mouse_pos);
last_button_state &= (MouseButton)~mask; last_button_state.clear_flag(mask);
sc->set_button_mask(last_button_state); sc->set_button_mask(last_button_state);
ds->mouse_set_button_state(last_button_state); ds->mouse_set_button_state(last_button_state);

View File

@ -402,10 +402,10 @@ bool joypad::check_ff_features() {
return false; return false;
} }
static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) { static BitField<HatMask> process_hat_value(int p_min, int p_max, int p_value, bool p_offset_hat) {
int range = (p_max - p_min + 1); int range = (p_max - p_min + 1);
int value = p_value - p_min; int value = p_value - p_min;
HatMask hat_value = HatMask::CENTER; BitField<HatMask> hat_value;
if (range == 4) { if (range == 4) {
value *= 2; value *= 2;
} }
@ -415,31 +415,34 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse
switch (value) { switch (value) {
case 0: case 0:
hat_value = HatMask::UP; hat_value.set_flag(HatMask::UP);
break; break;
case 1: case 1:
hat_value = (HatMask::UP | HatMask::RIGHT); hat_value.set_flag(HatMask::UP);
hat_value.set_flag(HatMask::RIGHT);
break; break;
case 2: case 2:
hat_value = HatMask::RIGHT; hat_value.set_flag(HatMask::RIGHT);
break; break;
case 3: case 3:
hat_value = (HatMask::DOWN | HatMask::RIGHT); hat_value.set_flag(HatMask::DOWN);
hat_value.set_flag(HatMask::RIGHT);
break; break;
case 4: case 4:
hat_value = HatMask::DOWN; hat_value.set_flag(HatMask::DOWN);
break; break;
case 5: case 5:
hat_value = (HatMask::DOWN | HatMask::LEFT); hat_value.set_flag(HatMask::DOWN);
hat_value.set_flag(HatMask::LEFT);
break; break;
case 6: case 6:
hat_value = HatMask::LEFT; hat_value.set_flag(HatMask::LEFT);
break; break;
case 7: case 7:
hat_value = (HatMask::UP | HatMask::LEFT); hat_value.set_flag(HatMask::UP);
hat_value.set_flag(HatMask::LEFT);
break; break;
default: default:
hat_value = HatMask::CENTER;
break; break;
} }
return hat_value; return hat_value;
@ -474,7 +477,7 @@ void JoypadMacOS::process_joypads() {
for (int j = 0; j < joy.hat_elements.size(); j++) { for (int j = 0; j < joy.hat_elements.size(); j++) {
rec_element &elem = joy.hat_elements.write[j]; rec_element &elem = joy.hat_elements.write[j];
int value = joy.get_hid_element_state(&elem); int value = joy.get_hid_element_state(&elem);
HatMask hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat); BitField<HatMask> hat_value = process_hat_value(elem.min, elem.max, value, joy.offset_hat);
input->joy_hat(joy.id, hat_value); input->joy_hat(joy.id, hat_value);
} }

View File

@ -193,12 +193,12 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double
} }
} }
MouseButton mask = Input::get_singleton()->get_mouse_button_mask(); BitField<MouseButtonMask> mask = Input::get_singleton()->get_mouse_button_mask();
MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
if (ev->is_pressed()) { if (ev->is_pressed()) {
mask |= button_flag; mask.set_flag(button_flag);
} else if ((mask & button_flag) != MouseButton::NONE) { } else if (mask.has_flag(button_flag)) {
mask &= ~button_flag; mask.clear_flag(button_flag);
} else { } else {
// Received release event, but press was outside the canvas, so ignore. // Received release event, but press was outside the canvas, so ignore.
return false; return false;
@ -218,10 +218,10 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double
} }
void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) { void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_x, double p_rel_y, int p_modifiers) {
MouseButton input_mask = Input::get_singleton()->get_mouse_button_mask(); BitField<MouseButtonMask> input_mask = Input::get_singleton()->get_mouse_button_mask();
// For motion outside the canvas, only read mouse movement if dragging // For motion outside the canvas, only read mouse movement if dragging
// started inside the canvas; imitating desktop app behavior. // started inside the canvas; imitating desktop app behavior.
if (!get_singleton()->cursor_inside_canvas && input_mask == MouseButton::NONE) { if (!get_singleton()->cursor_inside_canvas && input_mask.is_empty()) {
return; return;
} }
@ -525,15 +525,17 @@ int DisplayServerWeb::mouse_wheel_callback(double p_delta_x, double p_delta_y) {
// Different browsers give wildly different delta values, and we can't // Different browsers give wildly different delta values, and we can't
// interpret deltaMode, so use default value for wheel events' factor. // interpret deltaMode, so use default value for wheel events' factor.
MouseButton button_flag = mouse_button_to_mask(ev->get_button_index()); MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
BitField<MouseButtonMask> button_mask = input->get_mouse_button_mask();
button_mask.set_flag(button_flag);
ev->set_pressed(true); ev->set_pressed(true);
ev->set_button_mask(input->get_mouse_button_mask() | button_flag); ev->set_button_mask(button_mask);
input->parse_input_event(ev); input->parse_input_event(ev);
Ref<InputEventMouseButton> release = ev->duplicate(); Ref<InputEventMouseButton> release = ev->duplicate();
release->set_pressed(false); release->set_pressed(false);
release->set_button_mask(MouseButton(input->get_mouse_button_mask() & ~button_flag)); release->set_button_mask(input->get_mouse_button_mask());
input->parse_input_event(release); input->parse_input_event(release);
return true; return true;

View File

@ -257,7 +257,7 @@ Point2i DisplayServerWindows::mouse_get_position() const {
return Point2i(p.x, p.y) - _get_screens_origin(); return Point2i(p.x, p.y) - _get_screens_origin();
} }
MouseButton DisplayServerWindows::mouse_get_button_state() const { BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const {
return last_button_state; return last_button_state;
} }
@ -3162,9 +3162,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_alt_pressed(alt_mem); mb->set_alt_pressed(alt_mem);
// mb->is_alt_pressed()=(wParam&MK_MENU)!=0; // mb->is_alt_pressed()=(wParam&MK_MENU)!=0;
if (mb->is_pressed()) { if (mb->is_pressed()) {
last_button_state |= mouse_button_to_mask(mb->get_button_index()); last_button_state.set_flag(mouse_button_to_mask(mb->get_button_index()));
} else { } else {
last_button_state &= ~mouse_button_to_mask(mb->get_button_index()); last_button_state.clear_flag(mouse_button_to_mask(mb->get_button_index()));
} }
mb->set_button_mask(last_button_state); mb->set_button_mask(last_button_state);
@ -3205,7 +3205,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Send release for mouse wheel. // Send release for mouse wheel.
Ref<InputEventMouseButton> mbd = mb->duplicate(); Ref<InputEventMouseButton> mbd = mb->duplicate();
mbd->set_window_id(window_id); mbd->set_window_id(window_id);
last_button_state &= ~mouse_button_to_mask(mbd->get_button_index()); last_button_state.clear_flag(mouse_button_to_mask(mbd->get_button_index()));
mbd->set_button_mask(last_button_state); mbd->set_button_mask(last_button_state);
mbd->set_pressed(false); mbd->set_pressed(false);
Input::get_singleton()->parse_input_event(mbd); Input::get_singleton()->parse_input_event(mbd);

View File

@ -446,7 +446,7 @@ class DisplayServerWindows : public DisplayServer {
bool shift_mem = false; bool shift_mem = false;
bool control_mem = false; bool control_mem = false;
bool meta_mem = false; bool meta_mem = false;
MouseButton last_button_state = MouseButton::NONE; BitField<MouseButtonMask> last_button_state;
bool use_raw_input = false; bool use_raw_input = false;
bool drop_events = false; bool drop_events = false;
bool in_dispatch_input_event = false; bool in_dispatch_input_event = false;
@ -506,7 +506,7 @@ public:
virtual void warp_mouse(const Point2i &p_position) override; virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override; virtual Point2i mouse_get_position() const override;
virtual MouseButton mouse_get_button_state() const override; virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override; virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override; virtual String clipboard_get() const override;

View File

@ -420,38 +420,43 @@ void JoypadWindows::process_joypads() {
} }
void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
HatMask dpad_val = (HatMask)0; BitField<HatMask> dpad_val;
// Should be -1 when centered, but according to docs: // Should be -1 when centered, but according to docs:
// "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows: // "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows:
// BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);" // BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);"
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks
if (LOWORD(p_dpad) == 0xFFFF) { if (LOWORD(p_dpad) == 0xFFFF) {
dpad_val = (HatMask)HatMask::CENTER; // Do nothing.
// dpad_val.set_flag(HatMask::CENTER);
} }
if (p_dpad == 0) { if (p_dpad == 0) {
dpad_val = (HatMask)HatMask::UP; dpad_val.set_flag(HatMask::UP);
} else if (p_dpad == 4500) { } else if (p_dpad == 4500) {
dpad_val = (HatMask)(HatMask::UP | HatMask::RIGHT); dpad_val.set_flag(HatMask::UP);
dpad_val.set_flag(HatMask::RIGHT);
} else if (p_dpad == 9000) { } else if (p_dpad == 9000) {
dpad_val = (HatMask)HatMask::RIGHT; dpad_val.set_flag(HatMask::RIGHT);
} else if (p_dpad == 13500) { } else if (p_dpad == 13500) {
dpad_val = (HatMask)(HatMask::RIGHT | HatMask::DOWN); dpad_val.set_flag(HatMask::RIGHT);
dpad_val.set_flag(HatMask::DOWN);
} else if (p_dpad == 18000) { } else if (p_dpad == 18000) {
dpad_val = (HatMask)HatMask::DOWN; dpad_val.set_flag(HatMask::DOWN);
} else if (p_dpad == 22500) { } else if (p_dpad == 22500) {
dpad_val = (HatMask)(HatMask::DOWN | HatMask::LEFT); dpad_val.set_flag(HatMask::DOWN);
dpad_val.set_flag(HatMask::LEFT);
} else if (p_dpad == 27000) { } else if (p_dpad == 27000) {
dpad_val = (HatMask)HatMask::LEFT; dpad_val.set_flag(HatMask::LEFT);
} else if (p_dpad == 31500) { } else if (p_dpad == 31500) {
dpad_val = (HatMask)(HatMask::LEFT | HatMask::UP); dpad_val.set_flag(HatMask::LEFT);
dpad_val.set_flag(HatMask::UP);
} }
input->joy_hat(p_device, dpad_val); input->joy_hat(p_device, dpad_val);
} }

View File

@ -62,7 +62,7 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mouse_button = p_event; Ref<InputEventMouseButton> mouse_button = p_event;
bool ui_accept = p_event->is_action("ui_accept", true) && !p_event->is_echo(); bool ui_accept = p_event->is_action("ui_accept", true) && !p_event->is_echo();
bool button_masked = mouse_button.is_valid() && (mouse_button_to_mask(mouse_button->get_button_index()) & button_mask) != MouseButton::NONE; bool button_masked = mouse_button.is_valid() && button_mask.has_flag(mouse_button_to_mask(mouse_button->get_button_index()));
if (button_masked || ui_accept) { if (button_masked || ui_accept) {
was_mouse_pressed = button_masked; was_mouse_pressed = button_masked;
on_action_event(p_event); on_action_event(p_event);
@ -323,11 +323,11 @@ BaseButton::ActionMode BaseButton::get_action_mode() const {
return action_mode; return action_mode;
} }
void BaseButton::set_button_mask(MouseButton p_mask) { void BaseButton::set_button_mask(BitField<MouseButtonMask> p_mask) {
button_mask = p_mask; button_mask = p_mask;
} }
MouseButton BaseButton::get_button_mask() const { BitField<MouseButtonMask> BaseButton::get_button_mask() const {
return button_mask; return button_mask;
} }

View File

@ -46,7 +46,7 @@ public:
}; };
private: private:
MouseButton button_mask = MouseButton::MASK_LEFT; BitField<MouseButtonMask> button_mask;
bool toggle_mode = false; bool toggle_mode = false;
bool shortcut_in_tooltip = true; bool shortcut_in_tooltip = true;
bool was_mouse_pressed = false; bool was_mouse_pressed = false;
@ -122,8 +122,8 @@ public:
void set_keep_pressed_outside(bool p_on); void set_keep_pressed_outside(bool p_on);
bool is_keep_pressed_outside() const; bool is_keep_pressed_outside() const;
void set_button_mask(MouseButton p_mask); void set_button_mask(BitField<MouseButtonMask> p_mask);
MouseButton get_button_mask() const; BitField<MouseButtonMask> get_button_mask() const;
void set_shortcut(const Ref<Shortcut> &p_shortcut); void set_shortcut(const Ref<Shortcut> &p_shortcut);
Ref<Shortcut> get_shortcut() const; Ref<Shortcut> get_shortcut() const;

View File

@ -380,13 +380,13 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
} }
if (symbol_lookup_on_click_enabled) { if (symbol_lookup_on_click_enabled) {
if (mm->is_command_or_control_pressed() && mm->get_button_mask() == MouseButton::NONE) { if (mm->is_command_or_control_pressed() && mm->get_button_mask().is_empty()) {
symbol_lookup_pos = get_line_column_at_pos(mpos); symbol_lookup_pos = get_line_column_at_pos(mpos);
symbol_lookup_new_word = get_word_at_pos(mpos); symbol_lookup_new_word = get_word_at_pos(mpos);
if (symbol_lookup_new_word != symbol_lookup_word) { if (symbol_lookup_new_word != symbol_lookup_word) {
emit_signal(SNAME("symbol_validate"), symbol_lookup_new_word); emit_signal(SNAME("symbol_validate"), symbol_lookup_new_word);
} }
} else if (!mm->is_command_or_control_pressed() || (mm->get_button_mask() != MouseButton::NONE && symbol_lookup_pos != get_line_column_at_pos(mpos))) { } else if (!mm->is_command_or_control_pressed() || (!mm->get_button_mask().is_empty() && symbol_lookup_pos != get_line_column_at_pos(mpos))) {
set_symbol_lookup_word_as_valid(false); set_symbol_lookup_word_as_valid(false);
} }
} }

View File

@ -394,7 +394,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
} }
} }
if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (m->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
if (selection.creating) { if (selection.creating) {
set_caret_at_pixel_pos(m->get_position().x); set_caret_at_pixel_pos(m->get_position().x);
selection_fill_at_caret(); selection_fill_at_caret();

View File

@ -395,10 +395,10 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) {
// Activate the item on release of either the left mouse button or // Activate the item on release of either the left mouse button or
// any mouse button held down when the popup was opened. // any mouse button held down when the popup was opened.
// This allows for opening the popup and triggering an action in a single mouse click. // This allows for opening the popup and triggering an action in a single mouse click.
if (button_idx == MouseButton::LEFT || (initial_button_mask & mouse_button_to_mask(button_idx)) != MouseButton::NONE) { if (button_idx == MouseButton::LEFT || initial_button_mask.has_flag(mouse_button_to_mask(button_idx))) {
bool was_during_grabbed_click = during_grabbed_click; bool was_during_grabbed_click = during_grabbed_click;
during_grabbed_click = false; during_grabbed_click = false;
initial_button_mask = MouseButton::NONE; initial_button_mask.clear();
// Disable clicks under a time threshold to avoid selection right when opening the popup. // Disable clicks under a time threshold to avoid selection right when opening the popup.
uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t now = OS::get_singleton()->get_ticks_msec();

View File

@ -92,7 +92,7 @@ class PopupMenu : public Popup {
Timer *submenu_timer = nullptr; Timer *submenu_timer = nullptr;
List<Rect2> autohide_areas; List<Rect2> autohide_areas;
Vector<Item> items; Vector<Item> items;
MouseButton initial_button_mask = MouseButton::NONE; BitField<MouseButtonMask> initial_button_mask;
bool during_grabbed_click = false; bool during_grabbed_click = false;
int mouse_over = -1; int mouse_over = -1;
int submenu_over = -1; int submenu_over = -1;

View File

@ -176,7 +176,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event; Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
if (drag.enabled) { if (drag.enabled) {
drag.diff_y += mm->get_relative().y; drag.diff_y += mm->get_relative().y;
double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y); double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y);

View File

@ -1906,7 +1906,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
mpos.x = get_size().x - mpos.x; mpos.x = get_size().x - mpos.x;
} }
if ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging. if (mm->get_button_mask().has_flag(MouseButtonMask::LEFT) && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging.
_reset_caret_blink_timer(); _reset_caret_blink_timer();
if (draw_minimap && !dragging_selection) { if (draw_minimap && !dragging_selection) {

View File

@ -114,7 +114,7 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
if (k.is_valid()) { if (k.is_valid()) {
if (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) { if (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) {
pan_key_pressed = k->is_pressed(); pan_key_pressed = k->is_pressed();
if (simple_panning_enabled || (Input::get_singleton()->get_mouse_button_mask() & MouseButton::LEFT) != MouseButton::NONE) { if (simple_panning_enabled || Input::get_singleton()->get_mouse_button_mask().has_flag(MouseButtonMask::LEFT)) {
is_dragging = pan_key_pressed; is_dragging = pan_key_pressed;
} }
return true; return true;

View File

@ -603,9 +603,9 @@ void Viewport::_process_picking() {
physics_last_mouse_state.meta = mb->is_meta_pressed(); physics_last_mouse_state.meta = mb->is_meta_pressed();
if (mb->is_pressed()) { if (mb->is_pressed()) {
physics_last_mouse_state.mouse_mask |= mouse_button_to_mask(mb->get_button_index()); physics_last_mouse_state.mouse_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
} else { } else {
physics_last_mouse_state.mouse_mask &= ~mouse_button_to_mask(mb->get_button_index()); physics_last_mouse_state.mouse_mask.clear_flag(mouse_button_to_mask(mb->get_button_index()));
// If touch mouse raised, assume we don't know last mouse pos until new events come // If touch mouse raised, assume we don't know last mouse pos until new events come
if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) {
@ -1496,19 +1496,20 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Point2 mpos = mb->get_position(); Point2 mpos = mb->get_position();
if (mb->is_pressed()) { if (mb->is_pressed()) {
Size2 pos = mpos; Size2 pos = mpos;
if (gui.mouse_focus_mask != MouseButton::NONE) { if (!gui.mouse_focus_mask.is_empty()) {
// Do not steal mouse focus and stuff while a focus mask exists. // Do not steal mouse focus and stuff while a focus mask exists.
gui.mouse_focus_mask |= mouse_button_to_mask(mb->get_button_index()); gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
} else { } else {
gui.mouse_focus = gui_find_control(pos); gui.mouse_focus = gui_find_control(pos);
gui.last_mouse_focus = gui.mouse_focus; gui.last_mouse_focus = gui.mouse_focus;
if (!gui.mouse_focus) { if (!gui.mouse_focus) {
gui.mouse_focus_mask = MouseButton::NONE; gui.mouse_focus_mask.clear();
return; return;
} }
gui.mouse_focus_mask = mouse_button_to_mask(mb->get_button_index()); gui.mouse_focus_mask.clear();
gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
if (mb->get_button_index() == MouseButton::LEFT) { if (mb->get_button_index() == MouseButton::LEFT) {
gui.drag_accum = Vector2(); gui.drag_accum = Vector2();
@ -1578,7 +1579,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_perform_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos); _perform_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos);
} }
gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. gui.mouse_focus_mask.clear_flag(mouse_button_to_mask(mb->get_button_index())); // Remove from mask.
if (!gui.mouse_focus) { if (!gui.mouse_focus) {
// Release event is only sent if a mouse focus (previously pressed button) exists. // Release event is only sent if a mouse focus (previously pressed button) exists.
@ -1597,7 +1598,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
// Disable mouse focus if needed before calling input, // Disable mouse focus if needed before calling input,
// this makes popups on mouse press event work better, // this makes popups on mouse press event work better,
// as the release will never be received otherwise. // as the release will never be received otherwise.
if (gui.mouse_focus_mask == MouseButton::NONE) { if (gui.mouse_focus_mask.is_empty()) {
gui.mouse_focus = nullptr; gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false; gui.forced_mouse_focus = false;
} }
@ -1619,7 +1620,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Point2 mpos = mm->get_position(); Point2 mpos = mm->get_position();
// Drag & drop. // Drag & drop.
if (!gui.drag_attempted && gui.mouse_focus && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { if (!gui.drag_attempted && gui.mouse_focus && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
gui.drag_accum += mm->get_relative(); gui.drag_accum += mm->get_relative();
float len = gui.drag_accum.length(); float len = gui.drag_accum.length();
if (len > 10) { if (len > 10) {
@ -1633,7 +1634,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.drag_data.get_type() != Variant::NIL) { if (gui.drag_data.get_type() != Variant::NIL) {
gui.mouse_focus = nullptr; gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false; gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE; gui.mouse_focus_mask.clear();
break; break;
} else { } else {
Control *drag_preview = _gui_get_drag_preview(); Control *drag_preview = _gui_get_drag_preview();
@ -1701,7 +1702,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
mm->set_velocity(velocity); mm->set_velocity(velocity);
mm->set_relative(rel); mm->set_relative(rel);
if (mm->get_button_mask() == MouseButton::NONE) { if (mm->get_button_mask().is_empty()) {
// Nothing pressed. // Nothing pressed.
bool is_tooltip_shown = false; bool is_tooltip_shown = false;
@ -1744,7 +1745,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *c = over; Control *c = over;
Vector2 cpos = pos; Vector2 cpos = pos;
while (c) { while (c) {
if (gui.mouse_focus_mask != MouseButton::NONE || c->has_point(cpos)) { if (!gui.mouse_focus_mask.is_empty() || c->has_point(cpos)) {
cursor_shape = c->get_cursor_shape(cpos); cursor_shape = c->get_cursor_shape(cpos);
} else { } else {
cursor_shape = Control::CURSOR_ARROW; cursor_shape = Control::CURSOR_ARROW;
@ -2103,7 +2104,7 @@ void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) { if (mb.is_valid()) {
if (!mb->is_pressed()) { if (!mb->is_pressed()) {
gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. gui.mouse_focus_mask.clear_flag(mouse_button_to_mask(mb->get_button_index())); // Remove from mask.
} }
} }
} }
@ -2194,7 +2195,7 @@ void Viewport::_gui_remove_control(Control *p_control) {
if (gui.mouse_focus == p_control) { if (gui.mouse_focus == p_control) {
gui.mouse_focus = nullptr; gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false; gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE; gui.mouse_focus_mask.clear();
} }
if (gui.last_mouse_focus == p_control) { if (gui.last_mouse_focus == p_control) {
gui.last_mouse_focus = nullptr; gui.last_mouse_focus = nullptr;
@ -2263,10 +2264,10 @@ void Viewport::_drop_mouse_over() {
void Viewport::_drop_mouse_focus() { void Viewport::_drop_mouse_focus() {
Control *c = gui.mouse_focus; Control *c = gui.mouse_focus;
MouseButton mask = gui.mouse_focus_mask; BitField<MouseButtonMask> mask = gui.mouse_focus_mask;
gui.mouse_focus = nullptr; gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false; gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE; gui.mouse_focus_mask.clear();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if ((int)mask & (1 << i)) { if ((int)mask & (1 << i)) {
@ -2374,7 +2375,7 @@ void Viewport::_post_gui_grab_click_focus() {
return; return;
} }
MouseButton mask = gui.mouse_focus_mask; BitField<MouseButtonMask> mask = gui.mouse_focus_mask;
Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
@ -3239,7 +3240,7 @@ void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) {
gui.mouse_focus = nullptr; gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false; gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE; gui.mouse_focus_mask.clear();
} }
} }

View File

@ -259,7 +259,7 @@ private:
bool control = false; bool control = false;
bool shift = false; bool shift = false;
bool meta = false; bool meta = false;
MouseButton mouse_mask = MouseButton::NONE; BitField<MouseButtonMask> mouse_mask;
} physics_last_mouse_state; } physics_last_mouse_state;
@ -358,7 +358,7 @@ private:
Control *mouse_focus = nullptr; Control *mouse_focus = nullptr;
Control *last_mouse_focus = nullptr; Control *last_mouse_focus = nullptr;
Control *mouse_click_grabber = nullptr; Control *mouse_click_grabber = nullptr;
MouseButton mouse_focus_mask = MouseButton::NONE; BitField<MouseButtonMask> mouse_focus_mask;
Control *key_focus = nullptr; Control *key_focus = nullptr;
Control *mouse_over = nullptr; Control *mouse_over = nullptr;
Control *drag_mouse_over = nullptr; Control *drag_mouse_over = nullptr;

View File

@ -331,8 +331,8 @@ Point2i DisplayServer::mouse_get_position() const {
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server."); ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
} }
MouseButton DisplayServer::mouse_get_button_state() const { BitField<MouseButtonMask> DisplayServer::mouse_get_button_state() const {
ERR_FAIL_V_MSG(MouseButton::NONE, "Mouse is not supported by this display server."); ERR_FAIL_V_MSG(0, "Mouse is not supported by this display server.");
} }
void DisplayServer::clipboard_set(const String &p_text) { void DisplayServer::clipboard_set(const String &p_text) {

View File

@ -230,7 +230,7 @@ public:
virtual void warp_mouse(const Point2i &p_position); virtual void warp_mouse(const Point2i &p_position);
virtual Point2i mouse_get_position() const; virtual Point2i mouse_get_position() const;
virtual MouseButton mouse_get_button_state() const; virtual BitField<MouseButtonMask> mouse_get_button_state() const;
virtual void clipboard_set(const String &p_text); virtual void clipboard_set(const String &p_text);
virtual String clipboard_get() const; virtual String clipboard_get() const;

View File

@ -3111,15 +3111,15 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
Point2 caret_pos = code_edit->get_caret_draw_pos(); Point2 caret_pos = code_edit->get_caret_draw_pos();
caret_pos.y += code_edit->get_line_height(); caret_pos.y += code_edit->get_line_height();
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, 0, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 1); CHECK(code_edit->get_code_completion_selected_index() == 1);
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, 0, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 0); CHECK(code_edit->get_code_completion_selected_index() == 0);
/* Single click selects. */ /* Single click selects. */
caret_pos.y += code_edit->get_line_height() * 2; caret_pos.y += code_edit->get_line_height() * 2;
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK(code_edit->get_code_completion_selected_index() == 2); CHECK(code_edit->get_code_completion_selected_index() == 2);
/* Double click inserts. */ /* Double click inserts. */
@ -3330,7 +3330,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
Point2 caret_pos = code_edit->get_caret_draw_pos(); Point2 caret_pos = code_edit->get_caret_draw_pos();
caret_pos.x += 60; caret_pos.x += 60;
SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, caret_pos, MouseButton::NONE, 0, Key::NONE);
CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text"); CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
SIGNAL_WATCH(code_edit, "symbol_validate"); SIGNAL_WATCH(code_edit, "symbol_validate");

View File

@ -891,8 +891,8 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
text_edit->grab_focus(); text_edit->grab_focus();
MessageQueue::get_singleton()->flush(); MessageQueue::get_singleton()->flush();
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 1), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 1), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->has_selection()); CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for s"); CHECK(text_edit->get_selected_text() == "for s");
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_POINTER); CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_POINTER);
@ -903,12 +903,12 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_line() == 1); CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 5); CHECK(text_edit->get_caret_column() == 5);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 9), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 9), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
text_edit->set_selecting_enabled(false); text_edit->set_selecting_enabled(false);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 1), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 1), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_caret_line() == 1); CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 5); CHECK(text_edit->get_caret_column() == 5);
@ -935,7 +935,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_column() == 3); CHECK(text_edit->get_caret_column() == 3);
SIGNAL_CHECK("caret_changed", empty_signal_args); SIGNAL_CHECK("caret_changed", empty_signal_args);
SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->has_selection()); CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for selection"); CHECK(text_edit->get_selected_text() == "for selection");
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD); CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_WORD);
@ -949,7 +949,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
Point2i line_0 = text_edit->get_pos_at_line_column(0, 0); Point2i line_0 = text_edit->get_pos_at_line_column(0, 0);
line_0.y /= 2; line_0.y /= 2;
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
text_edit->set_selecting_enabled(false); text_edit->set_selecting_enabled(false);
@ -968,7 +968,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
MessageQueue::get_singleton()->flush(); MessageQueue::get_singleton()->flush();
SEND_GUI_DOUBLE_CLICK(text_edit, text_edit->get_pos_at_line_column(0, 2), Key::NONE); SEND_GUI_DOUBLE_CLICK(text_edit, text_edit->get_pos_at_line_column(0, 2), Key::NONE);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 2), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 2), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->has_selection()); CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for selection"); CHECK(text_edit->get_selected_text() == "for selection");
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_LINE); CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_LINE);
@ -981,12 +981,12 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
Point2i line_0 = text_edit->get_pos_at_line_column(0, 0); Point2i line_0 = text_edit->get_pos_at_line_column(0, 0);
line_0.y /= 2; line_0.y /= 2;
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
text_edit->set_selecting_enabled(false); text_edit->set_selecting_enabled(false);
SEND_GUI_DOUBLE_CLICK(text_edit, text_edit->get_pos_at_line_column(0, 2), Key::NONE); SEND_GUI_DOUBLE_CLICK(text_edit, text_edit->get_pos_at_line_column(0, 2), Key::NONE);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 2), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 2), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_caret_line() == 1); CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 0); CHECK(text_edit->get_caret_column() == 0);
@ -1000,8 +1000,8 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
text_edit->set_text("this is some text\nfor selection"); text_edit->set_text("this is some text\nfor selection");
MessageQueue::get_singleton()->flush(); MessageQueue::get_singleton()->flush();
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 0), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE | KeyModifierMask::SHIFT); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE | KeyModifierMask::SHIFT);
CHECK(text_edit->has_selection()); CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for s"); CHECK(text_edit->get_selected_text() == "for s");
CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_POINTER); CHECK(text_edit->get_selection_mode() == TextEdit::SELECTION_MODE_POINTER);
@ -1012,12 +1012,12 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_line() == 1); CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 5); CHECK(text_edit->get_caret_column() == 5);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 9), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 9), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
text_edit->set_selecting_enabled(false); text_edit->set_selecting_enabled(false);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 0), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 0), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE | KeyModifierMask::SHIFT); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE | KeyModifierMask::SHIFT);
CHECK_FALSE(text_edit->has_selection()); CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_caret_line() == 1); CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 5); CHECK(text_edit->get_caret_column() == 5);
@ -1149,19 +1149,19 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
Point2i line_0 = text_edit->get_pos_at_line_column(0, 0); Point2i line_0 = text_edit->get_pos_at_line_column(0, 0);
line_0.y /= 2; line_0.y /= 2;
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, line_0, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->is_mouse_over_selection()); CHECK(text_edit->is_mouse_over_selection());
SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->get_viewport()->gui_is_dragging()); CHECK(text_edit->get_viewport()->gui_is_dragging());
CHECK(text_edit->get_viewport()->gui_get_drag_data() == "drag me"); CHECK(text_edit->get_viewport()->gui_get_drag_data() == "drag me");
line_0 = target_text_edit->get_pos_at_line_column(0, 0); line_0 = target_text_edit->get_pos_at_line_column(0, 0);
line_0.y /= 2; line_0.y /= 2;
line_0.x += 401; // As empty add one. line_0.x += 401; // As empty add one.
SEND_GUI_MOUSE_MOTION_EVENT(target_text_edit, line_0, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_MOTION_EVENT(target_text_edit, line_0, MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->get_viewport()->gui_is_dragging()); CHECK(text_edit->get_viewport()->gui_is_dragging());
SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(target_text_edit, line_0, MouseButton::LEFT, MouseButton::MASK_LEFT, Key::NONE); SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(target_text_edit, line_0, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->get_viewport()->gui_is_dragging()); CHECK_FALSE(text_edit->get_viewport()->gui_is_dragging());
CHECK(text_edit->get_text() == ""); CHECK(text_edit->get_text() == "");
@ -3093,14 +3093,14 @@ TEST_CASE("[SceneTree][TextEdit] context menu") {
CHECK_FALSE(text_edit->is_context_menu_enabled()); CHECK_FALSE(text_edit->is_context_menu_enabled());
CHECK_FALSE(text_edit->is_menu_visible()); CHECK_FALSE(text_edit->is_menu_visible());
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(600, 10), MouseButton::RIGHT, MouseButton::MASK_RIGHT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(600, 10), MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
CHECK_FALSE(text_edit->is_menu_visible()); CHECK_FALSE(text_edit->is_menu_visible());
text_edit->set_context_menu_enabled(true); text_edit->set_context_menu_enabled(true);
CHECK(text_edit->is_context_menu_enabled()); CHECK(text_edit->is_context_menu_enabled());
CHECK_FALSE(text_edit->is_menu_visible()); CHECK_FALSE(text_edit->is_menu_visible());
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(700, 10), MouseButton::RIGHT, MouseButton::MASK_RIGHT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(700, 10), MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
CHECK(text_edit->is_menu_visible()); CHECK(text_edit->is_menu_visible());
memdelete(text_edit); memdelete(text_edit);
@ -3340,13 +3340,13 @@ TEST_CASE("[SceneTree][TextEdit] caret") {
text_edit->set_move_caret_on_right_click_enabled(false); text_edit->set_move_caret_on_right_click_enabled(false);
CHECK_FALSE(text_edit->is_move_caret_on_right_click_enabled()); CHECK_FALSE(text_edit->is_move_caret_on_right_click_enabled());
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(100, 1), MouseButton::RIGHT, MouseButton::MASK_RIGHT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(100, 1), MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
CHECK(text_edit->get_caret_column() == caret_col); CHECK(text_edit->get_caret_column() == caret_col);
text_edit->set_move_caret_on_right_click_enabled(true); text_edit->set_move_caret_on_right_click_enabled(true);
CHECK(text_edit->is_move_caret_on_right_click_enabled()); CHECK(text_edit->is_move_caret_on_right_click_enabled());
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(100, 1), MouseButton::RIGHT, MouseButton::MASK_RIGHT, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(100, 1), MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
CHECK(text_edit->get_caret_column() != caret_col); CHECK(text_edit->get_caret_column() != caret_col);
text_edit->set_move_caret_on_right_click_enabled(false); text_edit->set_move_caret_on_right_click_enabled(false);
@ -3860,28 +3860,28 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
// Scroll. // Scroll.
int v_scroll = text_edit->get_v_scroll(); int v_scroll = text_edit->get_v_scroll();
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
CHECK(text_edit->get_v_scroll() > v_scroll); CHECK(text_edit->get_v_scroll() > v_scroll);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
CHECK(text_edit->get_v_scroll() == v_scroll); CHECK(text_edit->get_v_scroll() == v_scroll);
// smooth scroll speed. // smooth scroll speed.
text_edit->set_smooth_scroll_enabled(true); text_edit->set_smooth_scroll_enabled(true);
v_scroll = text_edit->get_v_scroll(); v_scroll = text_edit->get_v_scroll();
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() >= v_scroll); CHECK(text_edit->get_v_scroll() >= v_scroll);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() == v_scroll); CHECK(text_edit->get_v_scroll() == v_scroll);
v_scroll = text_edit->get_v_scroll(); v_scroll = text_edit->get_v_scroll();
text_edit->set_v_scroll_speed(10000); text_edit->set_v_scroll_speed(10000);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() >= v_scroll); CHECK(text_edit->get_v_scroll() >= v_scroll);
SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
CHECK(text_edit->get_v_scroll() == v_scroll); CHECK(text_edit->get_v_scroll() == v_scroll);

View File

@ -136,7 +136,7 @@ int register_test_command(String p_command, TestFunc p_function);
// SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::META). // SEND_GUI_KEY_EVENT - takes an object and a keycode set. e.g SEND_GUI_KEY_EVENT(code_edit, Key::A | KeyModifierMask::META).
// SEND_GUI_MOUSE_BUTTON_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None); // SEND_GUI_MOUSE_BUTTON_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
// SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None); // SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT - takes an object, position, mouse button, mouse mask and modifiers e.g SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(code_edit, Vector2(50, 50), MOUSE_BUTTON_NONE, MOUSE_BUTTON_NONE, Key::None);
// SEND_GUI_MOUSE_MOTION_EVENT - takes an object, position, mouse mask and modifiers e.g SEND_GUI_MOUSE_MOTION_EVENT(code_edit, Vector2(50, 50), MouseButton::MASK_LEFT, KeyModifierMask::META); // SEND_GUI_MOUSE_MOTION_EVENT - takes an object, position, mouse mask and modifiers e.g SEND_GUI_MOUSE_MOTION_EVENT(code_edit, Vector2(50, 50), MouseButtonMask::LEFT, KeyModifierMask::META);
// SEND_GUI_DOUBLE_CLICK - takes an object, position and modifiers. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50), KeyModifierMask::META); // SEND_GUI_DOUBLE_CLICK - takes an object, position and modifiers. e.g SEND_GUI_DOUBLE_CLICK(code_edit, Vector2(50, 50), KeyModifierMask::META);
#define SEND_GUI_ACTION(m_object, m_action) \ #define SEND_GUI_ACTION(m_object, m_action) \
@ -190,7 +190,7 @@ int register_test_command(String p_command, TestFunc p_function);
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos, m_modifers) \ #define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos, m_modifers) \
{ \ { \
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, MouseButton::LEFT, m_modifers); \ _CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, 0, m_modifers); \
event->set_double_click(true); \ event->set_double_click(true); \
m_object->get_viewport()->push_input(event); \ m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \ MessageQueue::get_singleton()->flush(); \