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
StringName enum_name;
bool ignore_value_in_docs = false;
bool is_bitfield = false;
#endif
const char *name = nullptr;
int64_t value = 0;
@ -46,9 +47,10 @@ struct _CoreConstant {
_CoreConstant() {}
#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),
ignore_value_in_docs(p_ignore_value_in_docs),
is_bitfield(p_is_bitfield),
name(p_name),
value(p_value) {
}
@ -70,13 +72,22 @@ static Vector<_CoreConstant> _global_constants;
#define BIND_CORE_ENUM_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.
#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));
#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) \
_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) \
_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) \
_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.
#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));
#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) \
_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) \
_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, YDIAERESIS);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, CMD_OR_CTRL);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, SHIFT);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, ALT);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, META);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, CTRL);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, KPAD);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, GROUP_SWITCH);
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CMD_OR_CTRL);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, SHIFT);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, ALT);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, META);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CTRL);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, KPAD);
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, LEFT);
@ -459,11 +479,12 @@ void register_global_constants() {
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_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_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_MIDDLE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON1);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON2);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, LEFT);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, RIGHT);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MIDDLE);
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, A);
@ -622,50 +643,50 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NONE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORAGE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CLASS_IS_BITFIELD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKABLE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_GROUP);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CATEGORY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SUBGROUP);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_BITFIELD);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_VARIABLE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NULL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_CLASS_IS_ENUM);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NIL_IS_VARIANT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_INTERNAL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_HIGH_END_GFX);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_KEYING_INCREMENTS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFERRED_SET_RESOURCE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_READ_ONLY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_ARRAY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORE_IF_NULL);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_ENUM);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NIL_IS_VARIANT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_INTERNAL);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_HIGH_END_GFX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_KEYING_INCREMENTS);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFERRED_SET_RESOURCE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_READ_ONLY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_ARRAY);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_EDITOR);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT_INTL);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_EDITOR);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NORMAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_EDITOR);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_CONST);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VARARG);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_NORMAL);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_EDITOR);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_CONST);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VIRTUAL);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VARARG);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_STATIC);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAGS_DEFAULT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
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;
}
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) {
return _global_constants[p_idx].ignore_value_in_docs;
}
@ -761,6 +786,10 @@ StringName CoreConstants::get_global_constant_enum(int p_idx) {
return StringName();
}
bool CoreConstants::is_global_constant_bitfield(int p_idx) {
return false;
}
bool CoreConstants::get_ignore_value_in_docs(int p_idx) {
return false;
}

View File

@ -37,6 +37,7 @@ class CoreConstants {
public:
static int get_global_constant_count();
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 const char *get_global_constant_name(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);
String enum_name = CoreConstants::get_global_constant_enum(i);
String name = CoreConstants::get_global_constant_name(i);
bool bitfield = CoreConstants::is_global_constant_bitfield(i);
if (!enum_name.is_empty()) {
enum_list[enum_name].push_back(Pair<String, int64_t>(name, value));
} else {
Dictionary d;
d["name"] = name;
d["value"] = value;
d["is_bitfield"] = bitfield;
constants.push_back(d);
}
}

View File

@ -237,7 +237,7 @@ bool Input::is_anything_pressed() const {
}
return !keys_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 {
@ -252,7 +252,7 @@ bool Input::is_physical_key_pressed(Key p_keycode) const {
bool Input::is_mouse_button_pressed(MouseButton p_button) const {
_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) {
@ -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_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 {
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();
@ -534,7 +534,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Vector2 relative = mm->get_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;
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_button_index(MouseButton::LEFT);
button_event->set_double_click(st->is_double_tap());
BitField<MouseButtonMask> ev_bm = mouse_button_mask;
if (st->is_pressed()) {
button_event->set_button_mask(MouseButton(mouse_button_mask | MouseButton::MASK_LEFT));
ev_bm.set_flag(MouseButtonMask::LEFT);
} 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);
}
@ -740,7 +743,7 @@ Point2 Input::get_last_mouse_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();
}
@ -821,7 +824,9 @@ void Input::ensure_touch_mouse_raised() {
button_event->set_global_position(mouse_pos);
button_event->set_pressed(false);
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);
}
@ -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_;
const Joypad &joy = joy_names[p_device];

View File

@ -82,7 +82,7 @@ public:
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
private:
MouseButton mouse_button_mask = MouseButton::NONE;
BitField<MouseButtonMask> mouse_button_mask;
RBSet<Key> physical_keys_pressed;
RBSet<Key> keys_pressed;
@ -273,7 +273,7 @@ public:
Point2 get_mouse_position() const;
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);
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 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_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 remove_joy_mapping(String p_guid);

View File

@ -119,59 +119,18 @@ enum class MouseButton {
WHEEL_RIGHT = 7,
MB_XBUTTON1 = 8, // "XBUTTON1" 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) {
return MouseButton(1 << ((int)button - 1));
}
enum class MouseButtonMask {
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) {
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, 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);
inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
return MouseButtonMask(1 << ((int)button - 1));
}
#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());
}
Key InputEventWithModifiers::get_modifiers_mask() const {
Key mask = Key::NONE;
BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
BitField<KeyModifierMask> mask;
if (is_ctrl_pressed()) {
mask |= KeyModifierMask::CTRL;
mask.set_flag(KeyModifierMask::CTRL);
}
if (is_shift_pressed()) {
mask |= KeyModifierMask::SHIFT;
mask.set_flag(KeyModifierMask::SHIFT);
}
if (is_alt_pressed()) {
mask |= KeyModifierMask::ALT;
mask.set_flag(KeyModifierMask::ALT);
}
if (is_meta_pressed()) {
mask |= KeyModifierMask::META;
mask.set_flag(KeyModifierMask::META);
}
if (is_command_or_control_autoremap()) {
#ifdef MACOS_ENABLED
mask |= KeyModifierMask::META;
mask.set_flag(KeyModifierMask::META);
#else
mask |= KeyModifierMask::CTRL;
mask.set_flag(KeyModifierMask::CTRL);
#endif
}
return mask;
@ -356,11 +356,11 @@ bool InputEventKey::is_echo() 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 {
return physical_keycode | get_modifiers_mask();
return physical_keycode | (int64_t)get_modifiers_mask();
}
String InputEventKey::as_text() const {
@ -440,8 +440,8 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_ma
} else {
match = get_physical_keycode() == key->get_physical_keycode();
}
Key action_mask = get_modifiers_mask();
Key key_mask = key->get_modifiers_mask();
Key action_mask = (Key)(int64_t)get_modifiers_mask();
Key key_mask = (Key)(int64_t)key->get_modifiers_mask();
if (key->is_pressed()) {
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;
emit_changed();
}
MouseButton InputEventMouse::get_button_mask() const {
BitField<MouseButtonMask> InputEventMouse::get_button_mask() const {
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;
Key action_modifiers_mask = get_modifiers_mask();
Key button_modifiers_mask = mb->get_modifiers_mask();
Key action_modifiers_mask = (Key)(int64_t)get_modifiers_mask();
Key button_modifiers_mask = (Key)(int64_t)mb->get_modifiers_mask();
if (mb->is_pressed()) {
match &= (action_modifiers_mask & button_modifiers_mask) == action_modifiers_mask;
}
@ -808,26 +808,23 @@ String InputEventMouseMotion::as_text() const {
}
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);
switch (mouse_button_mask) {
case MouseButton::MASK_LEFT:
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]));
break;
case MouseButton::MASK_MIDDLE:
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]));
break;
case MouseButton::MASK_RIGHT:
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]));
break;
case MouseButton::MASK_XBUTTON1:
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]));
break;
case MouseButton::MASK_XBUTTON2:
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]));
break;
default:
break;
if (mouse_button_mask.has_flag(MouseButtonMask::LEFT)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]));
}
if (mouse_button_mask.has_flag(MouseButtonMask::MIDDLE)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]));
}
if (mouse_button_mask.has_flag(MouseButtonMask::RIGHT)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]));
}
if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON1)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]));
}
if (mouse_button_mask.has_flag(MouseButtonMask::MB_XBUTTON2)) {
button_mask_string += vformat(" (%s)", TTRGET(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]));
}
// 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);
Key get_modifiers_mask() const;
BitField<KeyModifierMask> get_modifiers_mask() const;
virtual String as_text() const override;
virtual String to_string() override;
@ -195,7 +195,7 @@ public:
class InputEventMouse : public InputEventWithModifiers {
GDCLASS(InputEventMouse, InputEventWithModifiers);
MouseButton button_mask = MouseButton::NONE;
BitField<MouseButtonMask> button_mask;
Vector2 pos;
Vector2 global_pos;
@ -204,8 +204,8 @@ protected:
static void _bind_methods();
public:
void set_button_mask(MouseButton p_mask);
MouseButton get_button_mask() const;
void set_button_mask(BitField<MouseButtonMask> p_mask);
BitField<MouseButtonMask> get_button_mask() const;
void set_position(const Vector2 &p_pos);
Vector2 get_position() const;

View File

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

View File

@ -146,22 +146,53 @@ VARIANT_ENUM_CAST(Side);
VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner);
VARIANT_ENUM_CAST(HatDir);
VARIANT_ENUM_CAST(HatMask);
VARIANT_BITFIELD_CAST(HatMask);
VARIANT_ENUM_CAST(JoyAxis);
VARIANT_ENUM_CAST(JoyButton);
VARIANT_ENUM_CAST(Key);
VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(MIDIMessage);
VARIANT_ENUM_CAST(MouseButton);
VARIANT_BITFIELD_CAST(MouseButtonMask);
VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HorizontalAlignment);
VARIANT_ENUM_CAST(VerticalAlignment);
VARIANT_ENUM_CAST(InlineAlignment);
VARIANT_ENUM_CAST(PropertyHint);
VARIANT_ENUM_CAST(PropertyUsageFlags);
VARIANT_BITFIELD_CAST(PropertyUsageFlags);
VARIANT_ENUM_CAST(Variant::Type);
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 <>
struct VariantCaster<char32_t> {
static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {

View File

@ -287,11 +287,14 @@ class BitField {
int64_t value = 0;
public:
_FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; }
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; }
_FORCE_INLINE_ void clear_flag(T p_flag) { return 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 & (int64_t)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(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 Variant() const { return value; }
};

View File

@ -2319,31 +2319,31 @@
<constant name="KEY_YDIAERESIS" value="255" enum="Key">
ÿ key.
</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.
</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.
</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.
</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.
</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.
</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.
</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.
</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.
</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.
</constant>
<constant name="MOUSE_BUTTON_NONE" value="0" enum="MouseButton">
@ -2376,19 +2376,19 @@
<constant name="MOUSE_BUTTON_XBUTTON2" value="9" enum="MouseButton">
Extra mouse button 2. This is sometimes present, usually to the sides of the mouse.
</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.
</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.
</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.
</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.
</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.
</constant>
<constant name="JOY_BUTTON_INVALID" value="-1" enum="JoyButton">
@ -2840,111 +2840,111 @@
</constant>
<constant name="PROPERTY_HINT_MAX" value="45" enum="PropertyHint">
</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.
</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).
</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).
</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].
</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].
</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.
</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].
</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.
</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].
</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 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].
</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.
</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.
</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 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 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 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 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 name="PROPERTY_USAGE_INTERNAL" value="262144" enum="PropertyUsageFlags">
<constant name="PROPERTY_USAGE_INTERNAL" value="262144" enum="PropertyUsageFlags" is_bitfield="true">
</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].
</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).
</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 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 name="PROPERTY_USAGE_KEYING_INCREMENTS" value="8388608" enum="PropertyUsageFlags">
<constant name="PROPERTY_USAGE_KEYING_INCREMENTS" value="8388608" enum="PropertyUsageFlags" is_bitfield="true">
</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 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 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 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].
</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.
</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).
</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).
</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).
</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.
</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.
</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.
</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.
</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.
</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.
</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.
</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).
</constant>
<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">
The [ButtonGroup] associated with the button. Not to be confused with node groups.
</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.
To allow both left-click and right-click, use [code]MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT[/code].
</member>

View File

@ -785,7 +785,7 @@
</description>
</method>
<method name="mouse_get_button_state" qualifiers="const">
<return type="int" enum="MouseButton" />
<return type="int" enum="MouseButtonMask" />
<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].
</description>

View File

@ -155,7 +155,7 @@
</description>
</method>
<method name="get_mouse_button_mask" qualifiers="const">
<return type="int" enum="MouseButton" />
<return type="int" enum="MouseButtonMask" />
<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].
</description>

View File

@ -10,7 +10,7 @@
<link title="InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<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.
</member>
<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) {
moving_selection = true;
emit_signal(SNAME("move_selection_begin"));
@ -5309,7 +5309,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
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.
box_selection->hide();
box_selecting = false;

View File

@ -468,7 +468,7 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
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;
if (x < total_metrics) {

View File

@ -544,7 +544,7 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
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;
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++) {
DocData::ConstantDoc cd;
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)) {
cd.value = itos(CoreConstants::get_global_constant_value(i));
cd.is_value_valid = true;

View File

@ -618,7 +618,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
if (is_layout_rtl()) {
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;
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;
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;
if (rel == 0) {
return;

View File

@ -37,7 +37,7 @@ void EditorTitleBar::input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
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());
if (w) {
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;
}
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_y) -= mm->get_relative().x * 0.01 * EDSCALE;
(*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()) {
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)));
//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();
}
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;
blend_pos *= blend_space->get_max_space() - 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();
}
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());
blend_pos.y = 1.0 - blend_pos.y;
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;
// 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);
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)
if (drag_type == DRAG_NONE) {
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();
// 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());
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.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());
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_y -= mm->get_relative().x * 0.01;
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);
}
@ -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);
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()) {
nav_mode = NAVIGATION_ORBIT;
} 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);
}
} 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()) {
nav_mode = NAVIGATION_ZOOM;
} else if (freelook_active) {
@ -1972,7 +1972,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
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);
if (nav_scheme == NAVIGATION_GODOT) {
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) {
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.y -= mm->get_relative().x * (0.02 * EDSCALE);
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;
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();
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;
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.
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;
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());
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);

View File

@ -36,7 +36,7 @@ void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
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;
x_rot += mm->get_relative().y * 0.01;
_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) {
return;
}
@ -242,7 +242,7 @@ void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask
hover_prev_pos = mouse_event_info.pos;
}
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;
@ -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) {
_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;
}
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) {
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
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();
_set_key_modifier_state(evd);
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);
Input::get_singleton()->parse_input_event(evd);
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);
}
MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) {
switch (button_mask) {
case MouseButton::MASK_LEFT:
MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) {
switch (MouseButtonMask(button_mask.operator int64_t())) {
case MouseButtonMask::LEFT:
return MouseButton::LEFT;
case MouseButton::MASK_RIGHT:
case MouseButtonMask::RIGHT:
return MouseButton::RIGHT;
case MouseButton::MASK_MIDDLE:
case MouseButtonMask::MIDDLE:
return MouseButton::MIDDLE;
case MouseButton::MASK_XBUTTON1:
case MouseButtonMask::MB_XBUTTON1:
return MouseButton::MB_XBUTTON1;
case MouseButton::MASK_XBUTTON2:
case MouseButtonMask::MB_XBUTTON2:
return MouseButton::MB_XBUTTON2;
default:
return MouseButton::NONE;
}
}
MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
MouseButton godot_button_mask = MouseButton::NONE;
BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
BitField<MouseButtonMask> godot_button_mask;
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) {
godot_button_mask |= MouseButton::MASK_RIGHT;
godot_button_mask.set_flag(MouseButtonMask::RIGHT);
}
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) {
godot_button_mask |= MouseButton::MASK_XBUTTON1;
godot_button_mask.set_flag(MouseButtonMask::MB_XBUTTON1);
}
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;

View File

@ -61,7 +61,7 @@ public:
int index = 0; // Can be either JoyAxis or JoyButton.
bool pressed = false;
float value = 0;
HatMask hat = HatMask::CENTER;
BitField<HatMask> hat;
};
private:
@ -70,7 +70,7 @@ private:
bool control_mem = false;
bool meta_mem = false;
MouseButton buttons_state = MouseButton::NONE;
BitField<MouseButtonMask> buttons_state;
Vector<TouchPos> touch;
MouseEventInfo mouse_event_info;
@ -78,12 +78,12 @@ private:
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
static MouseButton _button_index_from_mask(MouseButton button_mask);
static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask);
static MouseButton _button_index_from_mask(BitField<MouseButtonMask> 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);

View File

@ -624,8 +624,8 @@ Point2i DisplayServerAndroid::mouse_get_position() const {
return Input::get_singleton()->get_mouse_position();
}
MouseButton DisplayServerAndroid::mouse_get_button_state() const {
return (MouseButton)Input::get_singleton()->get_mouse_button_mask();
BitField<MouseButtonMask> DisplayServerAndroid::mouse_get_button_state() const {
return Input::get_singleton()->get_mouse_button_mask();
}
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);
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();
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;
jevent.device = p_device;
jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
HatMask hat = HatMask::CENTER;
BitField<HatMask> hat;
if (p_hat_x != 0) {
if (p_hat_x < 0) {
hat |= HatMask::LEFT;
hat.set_flag(HatMask::LEFT);
} else {
hat |= HatMask::RIGHT;
hat.set_flag(HatMask::RIGHT);
}
}
if (p_hat_y != 0) {
if (p_hat_y < 0) {
hat |= HatMask::UP;
hat.set_flag(HatMask::UP);
} else {
hat |= HatMask::DOWN;
hat.set_flag(HatMask::DOWN);
}
}
jevent.hat = hat;

View File

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

View File

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

View File

@ -458,7 +458,7 @@ Point2i DisplayServerX11::mouse_get_position() const {
return Vector2i();
}
MouseButton DisplayServerX11::mouse_get_button_state() const {
BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
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));
}
MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
MouseButton mask = mouse_button_to_mask(p_x11_button);
BitField<MouseButtonMask> DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
MouseButtonMask mask = mouse_button_to_mask(p_x11_button);
if (p_x11_type == ButtonPress) {
last_button_state |= mask;
last_button_state.set_flag(mask);
} else {
last_button_state &= ~mask;
last_button_state.clear_flag(mask);
}
return last_button_state;
@ -4171,13 +4171,13 @@ void DisplayServerX11::process_events() {
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} 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_pen_inverted(xi.pen_inverted);
_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_global_position(pos);
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);
uint64_t last_click_ms = 0;
MouseButton last_click_button_index = MouseButton::NONE;
MouseButton last_button_state = MouseButton::NONE;
BitField<MouseButtonMask> last_button_state;
bool app_focused = false;
uint64_t time_since_no_focus = 0;
@ -234,7 +234,7 @@ class DisplayServerX11 : public DisplayServer {
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 _flush_mouse_motion();
@ -344,7 +344,7 @@ public:
virtual void warp_mouse(const Point2i &p_position) 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 String clipboard_get() const override;

View File

@ -154,7 +154,7 @@ private:
CGEventSourceRef event_source;
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
MouseButton last_button_state = MouseButton::NONE;
BitField<MouseButtonMask> last_button_state;
bool drop_events = 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);
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;
void mouse_set_button_state(MouseButton p_state);
virtual MouseButton mouse_get_button_state() const override;
void mouse_set_button_state(BitField<MouseButtonMask> p_state);
virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;

View File

@ -2034,11 +2034,11 @@ Point2i DisplayServerMacOS::mouse_get_position() const {
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;
}
MouseButton DisplayServerMacOS::mouse_get_button_state() const {
BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const {
return last_button_state;
}

View File

@ -66,7 +66,7 @@
- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor;
- (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)updateLayerDelegate;
- (void)cancelComposition;

View File

@ -371,19 +371,21 @@
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();
if (!ds || !ds->has_window(window_id)) {
return;
}
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) {
last_button_state |= mask;
last_button_state.set_flag(mask);
} else {
last_button_state &= (MouseButton)~mask;
last_button_state.clear_flag(mask);
}
ds->mouse_set_button_state(last_button_state);
@ -407,10 +409,10 @@
- (void)mouseDown:(NSEvent *)event {
if (([event modifierFlags] & NSEventModifierFlagControl)) {
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 {
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 {
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 {
[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 {
[self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true];
[self processMouseEvent:event index:MouseButton::RIGHT pressed:true];
}
- (void)rightMouseDragged:(NSEvent *)event {
@ -477,16 +479,16 @@
}
- (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 {
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) {
[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) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:true];
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:true];
} else {
return;
}
@ -498,11 +500,11 @@
- (void)otherMouseUp:(NSEvent *)event {
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) {
[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) {
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:false];
[self processMouseEvent:event index:MouseButton::MB_XBUTTON2 pressed:false];
} else {
return;
}
@ -751,7 +753,8 @@
}
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;
sc.instantiate();
@ -763,7 +766,7 @@
sc->set_pressed(true);
sc->set_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);
ds->mouse_set_button_state(last_button_state);
@ -776,7 +779,7 @@
sc->set_pressed(false);
sc->set_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);
ds->mouse_set_button_state(last_button_state);

View File

@ -402,10 +402,10 @@ bool joypad::check_ff_features() {
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 value = p_value - p_min;
HatMask hat_value = HatMask::CENTER;
BitField<HatMask> hat_value;
if (range == 4) {
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) {
case 0:
hat_value = HatMask::UP;
hat_value.set_flag(HatMask::UP);
break;
case 1:
hat_value = (HatMask::UP | HatMask::RIGHT);
hat_value.set_flag(HatMask::UP);
hat_value.set_flag(HatMask::RIGHT);
break;
case 2:
hat_value = HatMask::RIGHT;
hat_value.set_flag(HatMask::RIGHT);
break;
case 3:
hat_value = (HatMask::DOWN | HatMask::RIGHT);
hat_value.set_flag(HatMask::DOWN);
hat_value.set_flag(HatMask::RIGHT);
break;
case 4:
hat_value = HatMask::DOWN;
hat_value.set_flag(HatMask::DOWN);
break;
case 5:
hat_value = (HatMask::DOWN | HatMask::LEFT);
hat_value.set_flag(HatMask::DOWN);
hat_value.set_flag(HatMask::LEFT);
break;
case 6:
hat_value = HatMask::LEFT;
hat_value.set_flag(HatMask::LEFT);
break;
case 7:
hat_value = (HatMask::UP | HatMask::LEFT);
hat_value.set_flag(HatMask::UP);
hat_value.set_flag(HatMask::LEFT);
break;
default:
hat_value = HatMask::CENTER;
break;
}
return hat_value;
@ -474,7 +477,7 @@ void JoypadMacOS::process_joypads() {
for (int j = 0; j < joy.hat_elements.size(); j++) {
rec_element &elem = joy.hat_elements.write[j];
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);
}

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();
MouseButton button_flag = mouse_button_to_mask(ev->get_button_index());
BitField<MouseButtonMask> mask = Input::get_singleton()->get_mouse_button_mask();
MouseButtonMask button_flag = mouse_button_to_mask(ev->get_button_index());
if (ev->is_pressed()) {
mask |= button_flag;
} else if ((mask & button_flag) != MouseButton::NONE) {
mask &= ~button_flag;
mask.set_flag(button_flag);
} else if (mask.has_flag(button_flag)) {
mask.clear_flag(button_flag);
} else {
// Received release event, but press was outside the canvas, so ignore.
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) {
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
// 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;
}
@ -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
// 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_button_mask(input->get_mouse_button_mask() | button_flag);
ev->set_button_mask(button_mask);
input->parse_input_event(ev);
Ref<InputEventMouseButton> release = ev->duplicate();
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);
return true;

View File

@ -257,7 +257,7 @@ Point2i DisplayServerWindows::mouse_get_position() const {
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;
}
@ -3162,9 +3162,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_alt_pressed(alt_mem);
// mb->is_alt_pressed()=(wParam&MK_MENU)!=0;
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 {
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);
@ -3205,7 +3205,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Send release for mouse wheel.
Ref<InputEventMouseButton> mbd = mb->duplicate();
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_pressed(false);
Input::get_singleton()->parse_input_event(mbd);

View File

@ -446,7 +446,7 @@ class DisplayServerWindows : public DisplayServer {
bool shift_mem = false;
bool control_mem = false;
bool meta_mem = false;
MouseButton last_button_state = MouseButton::NONE;
BitField<MouseButtonMask> last_button_state;
bool use_raw_input = false;
bool drop_events = false;
bool in_dispatch_input_event = false;
@ -506,7 +506,7 @@ public:
virtual void warp_mouse(const Point2i &p_position) 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 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) {
HatMask dpad_val = (HatMask)0;
BitField<HatMask> dpad_val;
// 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:
// BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);"
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks
if (LOWORD(p_dpad) == 0xFFFF) {
dpad_val = (HatMask)HatMask::CENTER;
// Do nothing.
// dpad_val.set_flag(HatMask::CENTER);
}
if (p_dpad == 0) {
dpad_val = (HatMask)HatMask::UP;
dpad_val.set_flag(HatMask::UP);
} 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) {
dpad_val = (HatMask)HatMask::RIGHT;
dpad_val.set_flag(HatMask::RIGHT);
} 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) {
dpad_val = (HatMask)HatMask::DOWN;
dpad_val.set_flag(HatMask::DOWN);
} 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) {
dpad_val = (HatMask)HatMask::LEFT;
dpad_val.set_flag(HatMask::LEFT);
} 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);
}

View File

@ -62,7 +62,7 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mouse_button = p_event;
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) {
was_mouse_pressed = button_masked;
on_action_event(p_event);
@ -323,11 +323,11 @@ BaseButton::ActionMode BaseButton::get_action_mode() const {
return action_mode;
}
void BaseButton::set_button_mask(MouseButton p_mask) {
void BaseButton::set_button_mask(BitField<MouseButtonMask> p_mask) {
button_mask = p_mask;
}
MouseButton BaseButton::get_button_mask() const {
BitField<MouseButtonMask> BaseButton::get_button_mask() const {
return button_mask;
}

View File

@ -46,7 +46,7 @@ public:
};
private:
MouseButton button_mask = MouseButton::MASK_LEFT;
BitField<MouseButtonMask> button_mask;
bool toggle_mode = false;
bool shortcut_in_tooltip = true;
bool was_mouse_pressed = false;
@ -122,8 +122,8 @@ public:
void set_keep_pressed_outside(bool p_on);
bool is_keep_pressed_outside() const;
void set_button_mask(MouseButton p_mask);
MouseButton get_button_mask() const;
void set_button_mask(BitField<MouseButtonMask> p_mask);
BitField<MouseButtonMask> get_button_mask() const;
void set_shortcut(const Ref<Shortcut> &p_shortcut);
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 (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_new_word = get_word_at_pos(mpos);
if (symbol_lookup_new_word != symbol_lookup_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);
}
}

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) {
set_caret_at_pixel_pos(m->get_position().x);
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
// 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.
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;
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.
uint64_t now = OS::get_singleton()->get_ticks_msec();

View File

@ -92,7 +92,7 @@ class PopupMenu : public Popup {
Timer *submenu_timer = nullptr;
List<Rect2> autohide_areas;
Vector<Item> items;
MouseButton initial_button_mask = MouseButton::NONE;
BitField<MouseButtonMask> initial_button_mask;
bool during_grabbed_click = false;
int mouse_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;
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) {
drag.diff_y += mm->get_relative().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;
}
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();
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 (pan_view_shortcut.is_valid() && pan_view_shortcut->matches_event(k)) {
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;
}
return true;

View File

@ -603,9 +603,9 @@ void Viewport::_process_picking() {
physics_last_mouse_state.meta = mb->is_meta_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 {
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 (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();
if (mb->is_pressed()) {
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.
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 {
gui.mouse_focus = gui_find_control(pos);
gui.last_mouse_focus = gui.mouse_focus;
if (!gui.mouse_focus) {
gui.mouse_focus_mask = MouseButton::NONE;
gui.mouse_focus_mask.clear();
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) {
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);
}
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) {
// 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,
// this makes popups on mouse press event work better,
// 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.forced_mouse_focus = false;
}
@ -1619,7 +1620,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Point2 mpos = mm->get_position();
// 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();
float len = gui.drag_accum.length();
if (len > 10) {
@ -1633,7 +1634,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.drag_data.get_type() != Variant::NIL) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE;
gui.mouse_focus_mask.clear();
break;
} else {
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_relative(rel);
if (mm->get_button_mask() == MouseButton::NONE) {
if (mm->get_button_mask().is_empty()) {
// Nothing pressed.
bool is_tooltip_shown = false;
@ -1744,7 +1745,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *c = over;
Vector2 cpos = pos;
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);
} else {
cursor_shape = Control::CURSOR_ARROW;
@ -2103,7 +2104,7 @@ void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
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) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE;
gui.mouse_focus_mask.clear();
}
if (gui.last_mouse_focus == p_control) {
gui.last_mouse_focus = nullptr;
@ -2263,10 +2264,10 @@ void Viewport::_drop_mouse_over() {
void Viewport::_drop_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.forced_mouse_focus = false;
gui.mouse_focus_mask = MouseButton::NONE;
gui.mouse_focus_mask.clear();
for (int i = 0; i < 3; i++) {
if ((int)mask & (1 << i)) {
@ -2374,7 +2375,7 @@ void Viewport::_post_gui_grab_click_focus() {
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);
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.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 shift = false;
bool meta = false;
MouseButton mouse_mask = MouseButton::NONE;
BitField<MouseButtonMask> mouse_mask;
} physics_last_mouse_state;
@ -358,7 +358,7 @@ private:
Control *mouse_focus = nullptr;
Control *last_mouse_focus = nullptr;
Control *mouse_click_grabber = nullptr;
MouseButton mouse_focus_mask = MouseButton::NONE;
BitField<MouseButtonMask> mouse_focus_mask;
Control *key_focus = nullptr;
Control *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.");
}
MouseButton DisplayServer::mouse_get_button_state() const {
ERR_FAIL_V_MSG(MouseButton::NONE, "Mouse is not supported by this display server.");
BitField<MouseButtonMask> DisplayServer::mouse_get_button_state() const {
ERR_FAIL_V_MSG(0, "Mouse is not supported by this display server.");
}
void DisplayServer::clipboard_set(const String &p_text) {

View File

@ -230,7 +230,7 @@ public:
virtual void warp_mouse(const Point2i &p_position);
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 String clipboard_get() const;

View File

@ -3111,15 +3111,15 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
Point2 caret_pos = code_edit->get_caret_draw_pos();
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);
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);
/* Single click selects. */
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);
/* Double click inserts. */
@ -3330,7 +3330,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
Point2 caret_pos = code_edit->get_caret_draw_pos();
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");
SIGNAL_WATCH(code_edit, "symbol_validate");

View File

@ -891,8 +891,8 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
text_edit->grab_focus();
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_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), 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), MouseButtonMask::LEFT, Key::NONE);
CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for s");
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_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());
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_MOTION_EVENT(text_edit, text_edit->get_pos_at_line_column(0, 7), 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), MouseButtonMask::LEFT, Key::NONE);
CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_caret_line() == 1);
CHECK(text_edit->get_caret_column() == 5);
@ -935,7 +935,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_caret_column() == 3);
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->get_selected_text() == "for selection");
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);
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());
text_edit->set_selecting_enabled(false);
@ -968,7 +968,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
MessageQueue::get_singleton()->flush();
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->get_selected_text() == "for selection");
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);
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());
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_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(text_edit->get_caret_line() == 1);
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");
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, 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, 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, MouseButtonMask::LEFT, Key::NONE | KeyModifierMask::SHIFT);
CHECK(text_edit->has_selection());
CHECK(text_edit->get_selected_text() == "for s");
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_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());
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, 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, 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, MouseButtonMask::LEFT, Key::NONE | KeyModifierMask::SHIFT);
CHECK_FALSE(text_edit->has_selection());
CHECK(text_edit->get_caret_line() == 1);
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);
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());
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_get_drag_data() == "drag me");
line_0 = target_text_edit->get_pos_at_line_column(0, 0);
line_0.y /= 2;
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());
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(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_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());
text_edit->set_context_menu_enabled(true);
CHECK(text_edit->is_context_menu_enabled());
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());
memdelete(text_edit);
@ -3340,13 +3340,13 @@ TEST_CASE("[SceneTree][TextEdit] caret") {
text_edit->set_move_caret_on_right_click_enabled(false);
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);
text_edit->set_move_caret_on_right_click_enabled(true);
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);
text_edit->set_move_caret_on_right_click_enabled(false);
@ -3860,28 +3860,28 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
// 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);
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);
// smooth scroll speed.
text_edit->set_smooth_scroll_enabled(true);
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);
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);
CHECK(text_edit->get_v_scroll() == v_scroll);
v_scroll = text_edit->get_v_scroll();
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);
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);
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_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_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);
#define SEND_GUI_ACTION(m_object, m_action) \
@ -188,12 +188,12 @@ int register_test_command(String p_command, TestFunc p_function);
MessageQueue::get_singleton()->flush(); \
}
#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); \
event->set_double_click(true); \
m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \
#define SEND_GUI_DOUBLE_CLICK(m_object, m_local_pos, m_modifers) \
{ \
_CREATE_GUI_MOUSE_EVENT(m_object, m_local_pos, MouseButton::LEFT, 0, m_modifers); \
event->set_double_click(true); \
m_object->get_viewport()->push_input(event); \
MessageQueue::get_singleton()->flush(); \
}
// We toggle _print_error_enabled to prevent display server not supported warnings.