mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-02-19 22:24:23 +01:00
Ported: [3.x, macOS, Windows, X11] Add stylus inverted/eraser support to InputEventMouseMotion event.
- hansemro
193d5c11f3
This commit is contained in:
parent
7ed3705487
commit
88fe196e79
@ -597,6 +597,14 @@ float InputEventMouseMotion::get_pressure() const {
|
||||
return pressure;
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::set_pen_inverted(bool p_inverted) {
|
||||
pen_inverted = p_inverted;
|
||||
}
|
||||
|
||||
bool InputEventMouseMotion::get_pen_inverted() const {
|
||||
return pen_inverted;
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
|
||||
relative = p_relative;
|
||||
}
|
||||
@ -628,6 +636,7 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
|
||||
|
||||
mm->set_position(l);
|
||||
mm->set_pressure(get_pressure());
|
||||
mm->set_pen_inverted(get_pen_inverted());
|
||||
mm->set_tilt(get_tilt());
|
||||
mm->set_global_position(g);
|
||||
|
||||
@ -660,7 +669,7 @@ String InputEventMouseMotion::as_text() const {
|
||||
button_mask_string = itos(get_button_mask());
|
||||
break;
|
||||
}
|
||||
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")";
|
||||
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + "), pen_inverted=(" + rtos(get_pen_inverted()) + ")";
|
||||
}
|
||||
|
||||
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
|
||||
@ -708,6 +717,9 @@ void InputEventMouseMotion::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure);
|
||||
ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pen_inverted", "pen_inverted"), &InputEventMouseMotion::set_pen_inverted);
|
||||
ClassDB::bind_method(D_METHOD("get_pen_inverted"), &InputEventMouseMotion::get_pen_inverted);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
|
||||
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
|
||||
|
||||
@ -716,12 +728,14 @@ void InputEventMouseMotion::_bind_methods() {
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
|
||||
}
|
||||
|
||||
InputEventMouseMotion::InputEventMouseMotion() {
|
||||
pressure = 0;
|
||||
pen_inverted = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
@ -386,6 +386,7 @@ class InputEventMouseMotion : public InputEventMouse {
|
||||
float pressure;
|
||||
Vector2 relative;
|
||||
Vector2 speed;
|
||||
bool pen_inverted;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@ -397,6 +398,9 @@ public:
|
||||
void set_pressure(float p_pressure);
|
||||
float get_pressure() const;
|
||||
|
||||
void set_pen_inverted(bool p_inverted);
|
||||
bool get_pen_inverted() const;
|
||||
|
||||
void set_relative(const Vector2 &p_relative);
|
||||
Vector2 get_relative() const;
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="pen_inverted" type="bool" setter="set_pen_inverted" getter="get_pen_inverted" default="false">
|
||||
Returns [code]true[/code] when using the eraser end of a stylus pen.
|
||||
[b]Note:[/b] This property is implemented on Linux, macOS and Windows.
|
||||
</member>
|
||||
<member name="pressure" type="float" setter="set_pressure" getter="get_pressure" default="0.0">
|
||||
Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code].
|
||||
</member>
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
NSTimeInterval last_warp = 0;
|
||||
bool ignore_warp = false;
|
||||
|
||||
bool last_pen_inverted = false;
|
||||
|
||||
Vector<KeyEvent> key_event_buffer;
|
||||
int key_event_pos;
|
||||
|
||||
|
@ -809,9 +809,15 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
|
||||
const Vector2 pos = get_mouse_pos(mpos);
|
||||
mm->set_position(pos);
|
||||
mm->set_pressure([event pressure]);
|
||||
if ([event subtype] == NSEventSubtypeTabletPoint) {
|
||||
NSEventSubtype subtype = [event subtype];
|
||||
if (subtype == NSEventSubtypeTabletPoint) {
|
||||
const NSPoint p = [event tilt];
|
||||
mm->set_tilt(Vector2(p.x, p.y));
|
||||
mm->set_pen_inverted(OS_OSX::singleton->last_pen_inverted);
|
||||
} else if (subtype == NSEventSubtypeTabletProximity) {
|
||||
// Check if using the eraser end of pen only on proximity event.
|
||||
OS_OSX::singleton->last_pen_inverted = [event pointingDeviceType] == NSPointingDeviceTypeEraser;
|
||||
mm->set_pen_inverted(OS_OSX::singleton->last_pen_inverted);
|
||||
}
|
||||
mm->set_global_position(pos);
|
||||
mm->set_speed(OS_OSX::singleton->input->get_last_mouse_speed());
|
||||
@ -3357,10 +3363,10 @@ void OS_OSX::force_process_input() {
|
||||
}
|
||||
|
||||
void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
|
||||
// Prevent main loop from sleeping and redraw window during modal popup display.
|
||||
// Prevent main loop from sleeping and redraw window during modal popup display.
|
||||
// Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates.
|
||||
|
||||
if (get_singleton()->get_main_loop() && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD) && !OS_OSX::singleton->is_resizing) {
|
||||
if (get_singleton()->get_main_loop() && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD) && !OS_OSX::singleton->is_resizing) {
|
||||
Main::force_redraw();
|
||||
if (!Main::is_iterating()) { // Avoid cyclic loop.
|
||||
Main::iteration();
|
||||
|
@ -490,6 +490,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
last_tilt = Vector2();
|
||||
}
|
||||
|
||||
last_pen_inverted = packet.pkStatus & TPS_INVERT;
|
||||
|
||||
POINT coords;
|
||||
GetCursorPos(&coords);
|
||||
ScreenToClient(hWnd, &coords);
|
||||
@ -504,6 +506,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
mm->set_shift(GetKeyState(VK_SHIFT) < 0);
|
||||
mm->set_alt(alt_mem);
|
||||
|
||||
mm->set_pen_inverted(last_pen_inverted);
|
||||
mm->set_pressure(last_pressure);
|
||||
mm->set_tilt(last_tilt);
|
||||
|
||||
@ -631,6 +634,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
Ref<InputEventMouseMotion> mm;
|
||||
mm.instance();
|
||||
|
||||
mm->set_pen_inverted(pen_info.penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER));
|
||||
|
||||
if (pen_info.penMask & PEN_MASK_PRESSURE) {
|
||||
mm->set_pressure((float)pen_info.pressure / 1024);
|
||||
} else {
|
||||
@ -742,14 +747,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
} else {
|
||||
last_tilt = Vector2();
|
||||
last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
|
||||
last_pen_inverted = false;
|
||||
}
|
||||
} else {
|
||||
last_tilt = Vector2();
|
||||
last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
|
||||
last_pen_inverted = false;
|
||||
}
|
||||
|
||||
mm->set_pressure(last_pressure);
|
||||
mm->set_tilt(last_tilt);
|
||||
mm->set_pen_inverted(last_pen_inverted);
|
||||
|
||||
mm->set_button_mask(last_button_state);
|
||||
|
||||
@ -1478,8 +1486,8 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
|
||||
if ((get_current_tablet_driver() == "wintab") && wintab_available) {
|
||||
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc);
|
||||
wtlc.lcOptions |= CXO_MESSAGES;
|
||||
wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
|
||||
wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
|
||||
wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
|
||||
wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
|
||||
wtlc.lcPktMode = 0;
|
||||
wtlc.lcOutOrgX = 0;
|
||||
wtlc.lcOutExtX = wtlc.lcInExtX;
|
||||
@ -1507,6 +1515,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
|
||||
last_pressure = 0;
|
||||
last_pressure_update = 0;
|
||||
last_tilt = Vector2();
|
||||
last_pen_inverted = false;
|
||||
|
||||
#if defined(OPENGL_ENABLED)
|
||||
|
||||
@ -3800,8 +3809,8 @@ void OS_Windows::set_current_tablet_driver(const String &p_driver) {
|
||||
if ((p_driver == "wintab") && wintab_available) {
|
||||
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wtlc);
|
||||
wtlc.lcOptions |= CXO_MESSAGES;
|
||||
wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
|
||||
wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
|
||||
wtlc.lcPktData = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
|
||||
wtlc.lcMoveMask = PK_STATUS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
|
||||
wtlc.lcPktMode = 0;
|
||||
wtlc.lcOutOrgX = 0;
|
||||
wtlc.lcOutExtX = wtlc.lcInExtX;
|
||||
@ -3845,6 +3854,10 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
||||
was_maximized = false;
|
||||
window_focused = true;
|
||||
|
||||
pen_inverted = false;
|
||||
block_mm = false;
|
||||
last_pen_inverted = false;
|
||||
|
||||
//Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
|
||||
HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
|
||||
if (wintab_lib) {
|
||||
|
@ -70,10 +70,13 @@
|
||||
#define DVC_ROTATION 18
|
||||
|
||||
#define CXO_MESSAGES 0x0004
|
||||
#define PK_STATUS 0x0002
|
||||
#define PK_NORMAL_PRESSURE 0x0400
|
||||
#define PK_TANGENT_PRESSURE 0x0800
|
||||
#define PK_ORIENTATION 0x1000
|
||||
|
||||
#define TPS_INVERT 0x0010 /* 1.1 */
|
||||
|
||||
typedef struct tagLOGCONTEXTW {
|
||||
WCHAR lcName[40];
|
||||
UINT lcOptions;
|
||||
@ -125,6 +128,7 @@ typedef struct tagORIENTATION {
|
||||
} ORIENTATION;
|
||||
|
||||
typedef struct tagPACKET {
|
||||
int pkStatus;
|
||||
int pkNormalPressure;
|
||||
int pkTangentPressure;
|
||||
ORIENTATION pkOrientation;
|
||||
@ -146,6 +150,14 @@ typedef UINT32 POINTER_FLAGS;
|
||||
typedef UINT32 PEN_FLAGS;
|
||||
typedef UINT32 PEN_MASK;
|
||||
|
||||
#ifndef PEN_FLAG_INVERTED
|
||||
#define PEN_FLAG_INVERTED 0x00000002
|
||||
#endif
|
||||
|
||||
#ifndef PEN_FLAG_ERASER
|
||||
#define PEN_FLAG_ERASER 0x00000004
|
||||
#endif
|
||||
|
||||
#ifndef PEN_MASK_PRESSURE
|
||||
#define PEN_MASK_PRESSURE 0x00000001
|
||||
#endif
|
||||
@ -271,11 +283,13 @@ class OS_Windows : public OS {
|
||||
int min_pressure;
|
||||
int max_pressure;
|
||||
bool tilt_supported;
|
||||
bool block_mm = false;
|
||||
bool pen_inverted;
|
||||
bool block_mm;
|
||||
|
||||
int last_pressure_update;
|
||||
float last_pressure;
|
||||
Vector2 last_tilt;
|
||||
bool last_pen_inverted;
|
||||
|
||||
enum {
|
||||
KEY_EVENT_BUFFER_SIZE = 512
|
||||
|
@ -635,6 +635,7 @@ bool OS_X11::refresh_device_info() {
|
||||
|
||||
xi.absolute_devices.clear();
|
||||
xi.touch_devices.clear();
|
||||
xi.pen_inverted_devices.clear();
|
||||
|
||||
int dev_count;
|
||||
XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
|
||||
@ -644,7 +645,8 @@ bool OS_X11::refresh_device_info() {
|
||||
if (!dev->enabled) {
|
||||
continue;
|
||||
}
|
||||
if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave)) {
|
||||
|
||||
if (!(dev->use == XISlavePointer || dev->use == XIFloatingSlave)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -713,6 +715,7 @@ bool OS_X11::refresh_device_info() {
|
||||
xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max);
|
||||
xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max);
|
||||
xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max);
|
||||
xi.pen_inverted_devices[dev->deviceid] = (bool)strstr(dev->name, "eraser");
|
||||
}
|
||||
|
||||
XIFreeDeviceInfo(info);
|
||||
@ -2525,7 +2528,7 @@ void OS_X11::process_xevents() {
|
||||
} break;
|
||||
case XI_RawMotion: {
|
||||
XIRawEvent *raw_event = (XIRawEvent *)event_data;
|
||||
int device_id = raw_event->deviceid;
|
||||
int device_id = raw_event->sourceid;
|
||||
|
||||
// Determine the axis used (called valuators in XInput for some forsaken reason)
|
||||
// Mask is a bitmask indicating which axes are involved.
|
||||
@ -2591,6 +2594,11 @@ void OS_X11::process_xevents() {
|
||||
values++;
|
||||
}
|
||||
|
||||
Map<int, bool>::Element *pen_inverted = xi.pen_inverted_devices.find(device_id);
|
||||
if (pen_inverted) {
|
||||
xi.pen_inverted = pen_inverted->value();
|
||||
}
|
||||
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
|
||||
// http://lists.libsdl.org/pipermail/commits-libsdl.org/2015-June/000282.html
|
||||
if (raw_event->time == xi.last_relative_time && rel_x == xi.relative_motion.x && rel_y == xi.relative_motion.y) {
|
||||
@ -2935,6 +2943,7 @@ void OS_X11::process_xevents() {
|
||||
} else {
|
||||
mm->set_pressure((get_mouse_button_state() & (1 << (BUTTON_LEFT - 1))) ? 1.0f : 0.0f);
|
||||
}
|
||||
mm->set_pen_inverted(xi.pen_inverted);
|
||||
mm->set_tilt(xi.tilt);
|
||||
|
||||
// Make the absolute position integral so it doesn't look _too_ weird :)
|
||||
|
@ -132,11 +132,13 @@ class OS_X11 : public OS_Unix {
|
||||
Map<int, Vector2> pen_pressure_range;
|
||||
Map<int, Vector2> pen_tilt_x_range;
|
||||
Map<int, Vector2> pen_tilt_y_range;
|
||||
Map<int, bool> pen_inverted_devices;
|
||||
XIEventMask all_event_mask;
|
||||
XIEventMask all_master_event_mask;
|
||||
Map<int, Vector2> state;
|
||||
double pressure;
|
||||
bool pressure_supported;
|
||||
bool pen_inverted;
|
||||
Vector2 tilt;
|
||||
Vector2 mouse_pos_to_filter;
|
||||
Vector2 relative_motion;
|
||||
|
Loading…
Reference in New Issue
Block a user