Added ability to set custom mouse cursors. Not hardware accelerated yet.

This commit is contained in:
Juan Linietsky 2015-09-24 18:06:15 -03:00
parent 59e1ad2773
commit 82a3304458
23 changed files with 611 additions and 407 deletions

View File

@ -64,6 +64,7 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("warp_mouse_pos","to"),&Input::warp_mouse_pos);
ObjectTypeDB::bind_method(_MD("action_press"),&Input::action_press);
ObjectTypeDB::bind_method(_MD("action_release"),&Input::action_release);
ObjectTypeDB::bind_method(_MD("set_custom_mouse_cursor","image:Texture","hotspot"),&Input::set_custom_mouse_cursor,DEFVAL(Vector2()));
BIND_CONSTANT( MOUSE_MODE_VISIBLE );
BIND_CONSTANT( MOUSE_MODE_HIDDEN );
@ -104,309 +105,3 @@ Input::Input() {
//////////////////////////////////////////////////////////
void InputDefault::SpeedTrack::update(const Vector2& p_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
uint32_t tdiff = tick-last_tick;
float delta_t = tdiff / 1000000.0;
last_tick=tick;
accum+=p_delta_p;
accum_t+=delta_t;
if (accum_t>max_ref_frame*10)
accum_t=max_ref_frame*10;
while( accum_t>=min_ref_frame ) {
float slice_t = min_ref_frame / accum_t;
Vector2 slice = accum*slice_t;
accum=accum-slice;
accum_t-=min_ref_frame;
speed=(slice/min_ref_frame).linear_interpolate(speed,min_ref_frame/max_ref_frame);
}
}
void InputDefault::SpeedTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
speed=Vector2();
accum_t=0;
}
InputDefault::SpeedTrack::SpeedTrack() {
min_ref_frame=0.1;
max_ref_frame=0.3;
reset();
}
bool InputDefault::is_key_pressed(int p_scancode) {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_scancode);
}
bool InputDefault::is_mouse_button_pressed(int p_button) {
_THREAD_SAFE_METHOD_
return (mouse_button_mask&(1<<p_button))!=0;
}
static int _combine_device(int p_value,int p_device) {
return p_value|(p_device<<20);
}
bool InputDefault::is_joy_button_pressed(int p_device, int p_button) {
_THREAD_SAFE_METHOD_
return joy_buttons_pressed.has(_combine_device(p_button,p_device));
}
bool InputDefault::is_action_pressed(const StringName& p_action) {
if (custom_action_press.has(p_action))
return true; //simpler
const List<InputEvent> *alist = InputMap::get_singleton()->get_action_list(p_action);
if (!alist)
return NULL;
for (const List<InputEvent>::Element *E=alist->front();E;E=E->next()) {
int device=E->get().device;
switch(E->get().type) {
case InputEvent::KEY: {
const InputEventKey &iek=E->get().key;
if ((keys_pressed.has(iek.scancode)))
return true;
} break;
case InputEvent::MOUSE_BUTTON: {
const InputEventMouseButton &iemb=E->get().mouse_button;
if(mouse_button_mask&(1<<iemb.button_index))
return true;
} break;
case InputEvent::JOYSTICK_BUTTON: {
const InputEventJoystickButton &iejb=E->get().joy_button;
int c = _combine_device(iejb.button_index,device);
if (joy_buttons_pressed.has(c))
return true;
} break;
}
}
return false;
}
float InputDefault::get_joy_axis(int p_device,int p_axis) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
if (joy_axis.has(c)) {
return joy_axis[c];
} else {
return 0;
}
}
String InputDefault::get_joy_name(int p_idx) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx];
};
void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
_THREAD_SAFE_METHOD_
joy_names[p_idx] = p_connected ? p_name : "";
emit_signal("joy_connection_changed", p_idx, p_connected);
};
Vector3 InputDefault::get_accelerometer() {
_THREAD_SAFE_METHOD_
return accelerometer;
}
void InputDefault::parse_input_event(const InputEvent& p_event) {
_THREAD_SAFE_METHOD_
switch(p_event.type) {
case InputEvent::KEY: {
if (p_event.key.echo)
break;
if (p_event.key.scancode==0)
break;
// print_line(p_event);
if (p_event.key.pressed)
keys_pressed.insert(p_event.key.scancode);
else
keys_pressed.erase(p_event.key.scancode);
} break;
case InputEvent::MOUSE_BUTTON: {
if (p_event.mouse_button.doubleclick)
break;
if (p_event.mouse_button.pressed)
mouse_button_mask|=(1<<p_event.mouse_button.button_index);
else
mouse_button_mask&=~(1<<p_event.mouse_button.button_index);
if (main_loop && emulate_touch && p_event.mouse_button.button_index==1) {
InputEventScreenTouch touch_event;
touch_event.index=0;
touch_event.pressed=p_event.mouse_button.pressed;
touch_event.x=p_event.mouse_button.x;
touch_event.y=p_event.mouse_button.y;
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.screen_touch=touch_event;
main_loop->input_event(ev);
}
} break;
case InputEvent::MOUSE_MOTION: {
if (main_loop && emulate_touch && p_event.mouse_motion.button_mask&1) {
InputEventScreenDrag drag_event;
drag_event.index=0;
drag_event.x=p_event.mouse_motion.x;
drag_event.y=p_event.mouse_motion.y;
drag_event.relative_x=p_event.mouse_motion.relative_x;
drag_event.relative_y=p_event.mouse_motion.relative_y;
drag_event.speed_x=p_event.mouse_motion.speed_x;
drag_event.speed_y=p_event.mouse_motion.speed_y;
InputEvent ev;
ev.type=InputEvent::SCREEN_DRAG;
ev.screen_drag=drag_event;
main_loop->input_event(ev);
}
} break;
case InputEvent::JOYSTICK_BUTTON: {
int c = _combine_device(p_event.joy_button.button_index,p_event.device);
if (p_event.joy_button.pressed)
joy_buttons_pressed.insert(c);
else
joy_buttons_pressed.erase(c);
} break;
case InputEvent::JOYSTICK_MOTION: {
set_joy_axis(p_event.device, p_event.joy_motion.axis, p_event.joy_motion.axis_value);
} break;
}
if (main_loop)
main_loop->input_event(p_event);
}
void InputDefault::set_joy_axis(int p_device,int p_axis,float p_value) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
joy_axis[c]=p_value;
}
void InputDefault::set_accelerometer(const Vector3& p_accel) {
_THREAD_SAFE_METHOD_
accelerometer=p_accel;
}
void InputDefault::set_main_loop(MainLoop *p_main_loop) {
main_loop=p_main_loop;
}
void InputDefault::set_mouse_pos(const Point2& p_posf) {
mouse_speed_track.update(p_posf-mouse_pos);
mouse_pos=p_posf;
}
Point2 InputDefault::get_mouse_pos() const {
return mouse_pos;
}
Point2 InputDefault::get_mouse_speed() const {
return mouse_speed_track.speed;
}
int InputDefault::get_mouse_button_mask() const {
return OS::get_singleton()->get_mouse_button_state();
}
void InputDefault::warp_mouse_pos(const Vector2& p_to) {
OS::get_singleton()->warp_mouse_pos(p_to);
}
void InputDefault::iteration(float p_step) {
}
void InputDefault::action_press(const StringName& p_action) {
if (custom_action_press.has(p_action)) {
custom_action_press[p_action]++;
} else {
custom_action_press[p_action]=1;
}
}
void InputDefault::action_release(const StringName& p_action){
ERR_FAIL_COND(!custom_action_press.has(p_action));
custom_action_press[p_action]--;
if (custom_action_press[p_action]==0) {
custom_action_press.erase(p_action);
}
}
void InputDefault::set_emulate_touch(bool p_emulate) {
emulate_touch=p_emulate;
}
bool InputDefault::is_emulating_touchscreen() const {
return emulate_touch;
}
InputDefault::InputDefault() {
mouse_button_mask=0;
emulate_touch=false;
main_loop=NULL;
}

View File

@ -80,82 +80,13 @@ public:
virtual bool is_emulating_touchscreen() const=0;
virtual void set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot=Vector2())=0;
virtual void set_mouse_in_window(bool p_in_window)=0;
Input();
};
VARIANT_ENUM_CAST(Input::MouseMode);
class InputDefault : public Input {
OBJ_TYPE( InputDefault, Input );
_THREAD_SAFE_CLASS_
int mouse_button_mask;
Set<int> keys_pressed;
Set<int> joy_buttons_pressed;
Map<int,float> joy_axis;
Map<StringName,int> custom_action_press;
Map<int, String> joy_names;
Vector3 accelerometer;
Vector2 mouse_pos;
MainLoop *main_loop;
bool emulate_touch;
struct SpeedTrack {
uint64_t last_tick;
Vector2 speed;
Vector2 accum;
float accum_t;
float min_ref_frame;
float max_ref_frame;
void update(const Vector2& p_delta_p);
void reset();
SpeedTrack();
};
SpeedTrack mouse_speed_track;
public:
virtual bool is_key_pressed(int p_scancode);
virtual bool is_mouse_button_pressed(int p_button);
virtual bool is_joy_button_pressed(int p_device, int p_button);
virtual bool is_action_pressed(const StringName& p_action);
virtual float get_joy_axis(int p_device,int p_axis);
String get_joy_name(int p_idx);
void joy_connection_changed(int p_idx, bool p_connected, String p_name);
virtual Vector3 get_accelerometer();
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
virtual int get_mouse_button_mask() const;
virtual void warp_mouse_pos(const Vector2& p_to);
void parse_input_event(const InputEvent& p_event);
void set_accelerometer(const Vector3& p_accel);
void set_joy_axis(int p_device,int p_axis,float p_value);
void set_main_loop(MainLoop *main_loop);
void set_mouse_pos(const Point2& p_posf);
void action_press(const StringName& p_action);
void action_release(const StringName& p_action);
void iteration(float p_step);
void set_emulate_touch(bool p_emulate);
virtual bool is_emulating_touchscreen() const;
InputDefault();
};
#endif // INPUT_H

View File

@ -45,7 +45,8 @@ void MainLoop::_bind_methods() {
BIND_VMETHOD( MethodInfo("_idle",PropertyInfo(Variant::REAL,"delta")) );
BIND_VMETHOD( MethodInfo("_finalize") );
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST);

View File

@ -47,6 +47,8 @@ protected:
public:
enum {
NOTIFICATION_WM_MOUSE_ENTER = 3,
NOTIFICATION_WM_MOUSE_EXIT = 4,
NOTIFICATION_WM_FOCUS_IN = 5,
NOTIFICATION_WM_FOCUS_OUT = 6,
NOTIFICATION_WM_QUIT_REQUEST = 7,

343
main/input_default.cpp Normal file
View File

@ -0,0 +1,343 @@
#include "input_default.h"
#include "servers/visual_server.h"
#include "os/os.h"
#include "input_map.h"
void InputDefault::SpeedTrack::update(const Vector2& p_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
uint32_t tdiff = tick-last_tick;
float delta_t = tdiff / 1000000.0;
last_tick=tick;
accum+=p_delta_p;
accum_t+=delta_t;
if (accum_t>max_ref_frame*10)
accum_t=max_ref_frame*10;
while( accum_t>=min_ref_frame ) {
float slice_t = min_ref_frame / accum_t;
Vector2 slice = accum*slice_t;
accum=accum-slice;
accum_t-=min_ref_frame;
speed=(slice/min_ref_frame).linear_interpolate(speed,min_ref_frame/max_ref_frame);
}
}
void InputDefault::SpeedTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
speed=Vector2();
accum_t=0;
}
InputDefault::SpeedTrack::SpeedTrack() {
min_ref_frame=0.1;
max_ref_frame=0.3;
reset();
}
bool InputDefault::is_key_pressed(int p_scancode) {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_scancode);
}
bool InputDefault::is_mouse_button_pressed(int p_button) {
_THREAD_SAFE_METHOD_
return (mouse_button_mask&(1<<p_button))!=0;
}
static int _combine_device(int p_value,int p_device) {
return p_value|(p_device<<20);
}
bool InputDefault::is_joy_button_pressed(int p_device, int p_button) {
_THREAD_SAFE_METHOD_
return joy_buttons_pressed.has(_combine_device(p_button,p_device));
}
bool InputDefault::is_action_pressed(const StringName& p_action) {
if (custom_action_press.has(p_action))
return true; //simpler
const List<InputEvent> *alist = InputMap::get_singleton()->get_action_list(p_action);
if (!alist)
return NULL;
for (const List<InputEvent>::Element *E=alist->front();E;E=E->next()) {
int device=E->get().device;
switch(E->get().type) {
case InputEvent::KEY: {
const InputEventKey &iek=E->get().key;
if ((keys_pressed.has(iek.scancode)))
return true;
} break;
case InputEvent::MOUSE_BUTTON: {
const InputEventMouseButton &iemb=E->get().mouse_button;
if(mouse_button_mask&(1<<iemb.button_index))
return true;
} break;
case InputEvent::JOYSTICK_BUTTON: {
const InputEventJoystickButton &iejb=E->get().joy_button;
int c = _combine_device(iejb.button_index,device);
if (joy_buttons_pressed.has(c))
return true;
} break;
}
}
return false;
}
float InputDefault::get_joy_axis(int p_device,int p_axis) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
if (joy_axis.has(c)) {
return joy_axis[c];
} else {
return 0;
}
}
String InputDefault::get_joy_name(int p_idx) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx];
};
void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
_THREAD_SAFE_METHOD_
joy_names[p_idx] = p_connected ? p_name : "";
emit_signal("joy_connection_changed", p_idx, p_connected);
};
Vector3 InputDefault::get_accelerometer() {
_THREAD_SAFE_METHOD_
return accelerometer;
}
void InputDefault::parse_input_event(const InputEvent& p_event) {
_THREAD_SAFE_METHOD_
switch(p_event.type) {
case InputEvent::KEY: {
if (p_event.key.echo)
break;
if (p_event.key.scancode==0)
break;
// print_line(p_event);
if (p_event.key.pressed)
keys_pressed.insert(p_event.key.scancode);
else
keys_pressed.erase(p_event.key.scancode);
} break;
case InputEvent::MOUSE_BUTTON: {
if (p_event.mouse_button.doubleclick)
break;
if (p_event.mouse_button.pressed)
mouse_button_mask|=(1<<p_event.mouse_button.button_index);
else
mouse_button_mask&=~(1<<p_event.mouse_button.button_index);
if (main_loop && emulate_touch && p_event.mouse_button.button_index==1) {
InputEventScreenTouch touch_event;
touch_event.index=0;
touch_event.pressed=p_event.mouse_button.pressed;
touch_event.x=p_event.mouse_button.x;
touch_event.y=p_event.mouse_button.y;
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.screen_touch=touch_event;
main_loop->input_event(ev);
}
} break;
case InputEvent::MOUSE_MOTION: {
if (main_loop && emulate_touch && p_event.mouse_motion.button_mask&1) {
InputEventScreenDrag drag_event;
drag_event.index=0;
drag_event.x=p_event.mouse_motion.x;
drag_event.y=p_event.mouse_motion.y;
drag_event.relative_x=p_event.mouse_motion.relative_x;
drag_event.relative_y=p_event.mouse_motion.relative_y;
drag_event.speed_x=p_event.mouse_motion.speed_x;
drag_event.speed_y=p_event.mouse_motion.speed_y;
InputEvent ev;
ev.type=InputEvent::SCREEN_DRAG;
ev.screen_drag=drag_event;
main_loop->input_event(ev);
}
} break;
case InputEvent::JOYSTICK_BUTTON: {
int c = _combine_device(p_event.joy_button.button_index,p_event.device);
if (p_event.joy_button.pressed)
joy_buttons_pressed.insert(c);
else
joy_buttons_pressed.erase(c);
} break;
case InputEvent::JOYSTICK_MOTION: {
set_joy_axis(p_event.device, p_event.joy_motion.axis, p_event.joy_motion.axis_value);
} break;
}
if (main_loop)
main_loop->input_event(p_event);
}
void InputDefault::set_joy_axis(int p_device,int p_axis,float p_value) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
joy_axis[c]=p_value;
}
void InputDefault::set_accelerometer(const Vector3& p_accel) {
_THREAD_SAFE_METHOD_
accelerometer=p_accel;
}
void InputDefault::set_main_loop(MainLoop *p_main_loop) {
main_loop=p_main_loop;
}
void InputDefault::set_mouse_pos(const Point2& p_posf) {
mouse_speed_track.update(p_posf-mouse_pos);
mouse_pos=p_posf;
if (custom_cursor.is_valid()) {
VisualServer::get_singleton()->cursor_set_pos(get_mouse_pos());
}
}
Point2 InputDefault::get_mouse_pos() const {
return mouse_pos;
}
Point2 InputDefault::get_mouse_speed() const {
return mouse_speed_track.speed;
}
int InputDefault::get_mouse_button_mask() const {
return OS::get_singleton()->get_mouse_button_state();
}
void InputDefault::warp_mouse_pos(const Vector2& p_to) {
OS::get_singleton()->warp_mouse_pos(p_to);
}
void InputDefault::iteration(float p_step) {
}
void InputDefault::action_press(const StringName& p_action) {
if (custom_action_press.has(p_action)) {
custom_action_press[p_action]++;
} else {
custom_action_press[p_action]=1;
}
}
void InputDefault::action_release(const StringName& p_action){
ERR_FAIL_COND(!custom_action_press.has(p_action));
custom_action_press[p_action]--;
if (custom_action_press[p_action]==0) {
custom_action_press.erase(p_action);
}
}
void InputDefault::set_emulate_touch(bool p_emulate) {
emulate_touch=p_emulate;
}
bool InputDefault::is_emulating_touchscreen() const {
return emulate_touch;
}
void InputDefault::set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot) {
if (custom_cursor==p_cursor)
return;
custom_cursor=p_cursor;
if (p_cursor.is_null()) {
set_mouse_mode(MOUSE_MODE_VISIBLE);
VisualServer::get_singleton()->cursor_set_visible(false);
} else {
set_mouse_mode(MOUSE_MODE_HIDDEN);
VisualServer::get_singleton()->cursor_set_visible(true);
VisualServer::get_singleton()->cursor_set_texture(custom_cursor->get_rid(),p_hotspot);
VisualServer::get_singleton()->cursor_set_pos(get_mouse_pos());
}
}
void InputDefault::set_mouse_in_window(bool p_in_window) {
if (custom_cursor.is_valid()) {
if (p_in_window) {
set_mouse_mode(MOUSE_MODE_HIDDEN);
VisualServer::get_singleton()->cursor_set_visible(true);
} else {
set_mouse_mode(MOUSE_MODE_VISIBLE);
VisualServer::get_singleton()->cursor_set_visible(false);
}
}
}
InputDefault::InputDefault() {
mouse_button_mask=0;
emulate_touch=false;
main_loop=NULL;
}

83
main/input_default.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef INPUT_DEFAULT_H
#define INPUT_DEFAULT_H
#include "os/input.h"
class InputDefault : public Input {
OBJ_TYPE( InputDefault, Input );
_THREAD_SAFE_CLASS_
int mouse_button_mask;
Set<int> keys_pressed;
Set<int> joy_buttons_pressed;
Map<int,float> joy_axis;
Map<StringName,int> custom_action_press;
Map<int, String> joy_names;
Vector3 accelerometer;
Vector2 mouse_pos;
MainLoop *main_loop;
bool emulate_touch;
struct SpeedTrack {
uint64_t last_tick;
Vector2 speed;
Vector2 accum;
float accum_t;
float min_ref_frame;
float max_ref_frame;
void update(const Vector2& p_delta_p);
void reset();
SpeedTrack();
};
SpeedTrack mouse_speed_track;
RES custom_cursor;
public:
virtual bool is_key_pressed(int p_scancode);
virtual bool is_mouse_button_pressed(int p_button);
virtual bool is_joy_button_pressed(int p_device, int p_button);
virtual bool is_action_pressed(const StringName& p_action);
virtual float get_joy_axis(int p_device,int p_axis);
String get_joy_name(int p_idx);
void joy_connection_changed(int p_idx, bool p_connected, String p_name);
virtual Vector3 get_accelerometer();
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
virtual int get_mouse_button_mask() const;
virtual void warp_mouse_pos(const Vector2& p_to);
void parse_input_event(const InputEvent& p_event);
void set_accelerometer(const Vector3& p_accel);
void set_joy_axis(int p_device,int p_axis,float p_value);
void set_main_loop(MainLoop *main_loop);
void set_mouse_pos(const Point2& p_posf);
void action_press(const StringName& p_action);
void action_release(const StringName& p_action);
void iteration(float p_step);
void set_emulate_touch(bool p_emulate);
virtual bool is_emulating_touchscreen() const;
virtual void set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot=Vector2());
virtual void set_mouse_in_window(bool p_in_window);
InputDefault();
};
#endif // INPUT_DEFAULT_H

View File

@ -75,7 +75,7 @@
#include "core/io/file_access_zip.h"
#include "translation.h"
#include "version.h"
#include "os/input.h"
#include "main/input_default.h"
#include "performance.h"
static Globals *globals=NULL;
@ -920,6 +920,9 @@ Error Main::setup2() {
id->set_emulate_touch(true);
}
}
MAIN_PRINT("Main: Load Remaps");
MAIN_PRINT("Main: Load Scene Types");
@ -927,6 +930,20 @@ Error Main::setup2() {
register_scene_types();
register_server_types();
GLOBAL_DEF("display/custom_mouse_cursor",String());
GLOBAL_DEF("display/custom_mouse_cursor_hotspot",Vector2());
Globals::get_singleton()->set_custom_property_info("display/custom_mouse_cursor",PropertyInfo(Variant::STRING,"display/custom_mouse_cursor",PROPERTY_HINT_FILE,"*.png,*.webp"));
if (String(Globals::get_singleton()->get("display/custom_mouse_cursor"))!=String()) {
print_line("use custom cursor");
Ref<Texture> cursor=ResourceLoader::load(Globals::get_singleton()->get("display/custom_mouse_cursor"));
if (cursor.is_valid()) {
print_line("loaded ok");
Vector2 hotspot = Globals::get_singleton()->get("display/custom_mouse_cursor_hotspot");
Input::get_singleton()->set_custom_mouse_cursor(cursor,hotspot);
}
}
#ifdef TOOLS_ENABLED
EditorNode::register_editor_types();
ObjectTypeDB::register_type<PCKPacker>(); // todo: move somewhere else

View File

@ -39,7 +39,7 @@
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/visual/rasterizer.h"
#include "main/input_default.h"
//#ifdef USE_JAVA_FILE_ACCESS

View File

@ -11,6 +11,7 @@
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "servers/audio/audio_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "main/input_default.h"
class OSFlash : public OS_Unix {

View File

@ -43,9 +43,11 @@
#include "servers/audio/sample_manager_sw.h"
#include "servers/spatial_sound/spatial_sound_server_sw.h"
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "main/input_default.h"
#include "game_center.h"
#include "in_app_store.h"
class AudioDriverIphone;
class RasterizerGLES2;

View File

@ -40,6 +40,7 @@
#include "servers/visual/rasterizer.h"
#include "audio_server_javascript.h"
#include "audio_driver_javascript.h"
#include "main/input_default.h"
typedef void (*GFXInitFunc)(void *ud,bool gl2,int w, int h, bool fs);
typedef int (*OpenURIFunc)(const String&);

View File

@ -32,7 +32,7 @@
#include "os/input.h"
#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
#include "servers/visual_server.h"
#include "servers/visual/visual_server_wrap_mt.h"
#include "servers/visual/rasterizer.h"

View File

@ -512,12 +512,26 @@ static int button_mask=0;
- (void)mouseExited:(NSEvent *)event
{
if (!OS_OSX::singleton)
return;
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(false);
// _glfwInputCursorEnter(window, GL_FALSE);
}
- (void)mouseEntered:(NSEvent *)event
{
// _glfwInputCursorEnter(window, GL_TRUE);
if (!OS_OSX::singleton)
return;
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(true);
}
- (void)viewDidChangeBackingProperties

View File

@ -30,7 +30,7 @@
#define OS_SERVER_H
#include "os/input.h"
#include "main/input_default.h"
#include "drivers/unix/os_unix.h"
#include "servers/visual_server.h"
#include "servers/visual/rasterizer.h"

View File

@ -323,11 +323,21 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
old_invalid=true;
outside=true;
if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (input)
input->set_mouse_in_window(false);
} break;
case WM_MOUSEMOVE: {
if (outside) {
//mouse enter
if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
if (input)
input->set_mouse_in_window(true);
CursorShape c=cursor_shape;
cursor_shape=CURSOR_MAX;

View File

@ -47,6 +47,7 @@
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "main/input_default.h"
#include <windows.h>

View File

@ -50,6 +50,8 @@
#include <fcntl.h>
#include <stdio.h>
#include "main/input_default.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/

View File

@ -1181,8 +1181,22 @@ void OS_X11::process_xevents() {
XVisibilityEvent * visibility = (XVisibilityEvent *)&event;
minimized = (visibility->state == VisibilityFullyObscured);
} break;
case LeaveNotify: {
case FocusIn:
if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (input)
input->set_mouse_in_window(false);
} break;
case EnterNotify: {
if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
if (input)
input->set_mouse_in_window(true);
} break;
case FocusIn:
minimized = false;
#ifdef NEW_WM_API
if(current_videomode.fullscreen) {

View File

@ -46,6 +46,7 @@
#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "main/input_default.h"
#include <X11/keysym.h>
#include <X11/Xlib.h>

View File

@ -187,30 +187,59 @@ void Skeleton::_notification(int p_what) {
Bone &b=bonesptr[i];
if (b.enabled) {
if (b.disable_rest) {
if (b.enabled) {
Transform pose=b.pose;
if (b.custom_pose_enable) {
Transform pose=b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
pose = b.custom_pose * pose;
}
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global * (b.rest * pose);
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global * pose;
} else {
b.pose_global=pose;
}
} else {
b.pose_global=b.rest * pose;
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global;
} else {
b.pose_global=Transform();
}
}
} else {
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global * b.rest;
if (b.enabled) {
Transform pose=b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global * (b.rest * pose);
} else {
b.pose_global=b.rest * pose;
}
} else {
b.pose_global=b.rest;
}
if (b.parent>=0) {
b.pose_global=bonesptr[b.parent].pose_global * b.rest;
} else {
b.pose_global=b.rest;
}
}
}
vs->skeleton_bone_set_transform( skeleton, i, b.pose_global * b.rest_global_inverse );
@ -315,6 +344,37 @@ void Skeleton::set_bone_parent(int p_bone, int p_parent) {
_make_dirty();
}
void Skeleton::unparent_bone_and_rest(int p_bone) {
ERR_FAIL_INDEX( p_bone, bones.size() );
int parent=bones[p_bone].parent;
while(parent>=0) {
bones[p_bone].rest = bones[parent].rest * bones[p_bone].rest;
parent=bones[parent].parent;
}
bones[p_bone].parent=-1;
bones[p_bone].rest_global_inverse=bones[p_bone].rest.affine_inverse(); //same thing
_make_dirty();
}
void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) {
ERR_FAIL_INDEX( p_bone, bones.size() );
bones[p_bone].disable_rest=p_disable;
}
bool Skeleton::is_bone_rest_disabled(int p_bone) const {
ERR_FAIL_INDEX_V( p_bone, bones.size(), false );
return bones[p_bone].disable_rest;
}
int Skeleton::get_bone_parent(int p_bone) const {
ERR_FAIL_INDEX_V( p_bone, bones.size(), -1 );
@ -522,9 +582,14 @@ void Skeleton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_bone_count"),&Skeleton::get_bone_count);
ObjectTypeDB::bind_method(_MD("unparent_bone_and_rest","bone_idx"),&Skeleton::unparent_bone_and_rest);
ObjectTypeDB::bind_method(_MD("get_bone_rest","bone_idx"),&Skeleton::get_bone_rest);
ObjectTypeDB::bind_method(_MD("set_bone_rest","bone_idx","rest"),&Skeleton::set_bone_rest);
ObjectTypeDB::bind_method(_MD("set_bone_disable_rest","bone_idx","disable"),&Skeleton::set_bone_disable_rest);
ObjectTypeDB::bind_method(_MD("is_bone_rest_disabled","bone_idx"),&Skeleton::is_bone_rest_disabled);
ObjectTypeDB::bind_method(_MD("bind_child_node_to_bone","bone_idx","node:Node"),&Skeleton::bind_child_node_to_bone);
ObjectTypeDB::bind_method(_MD("unbind_child_node_from_bone","bone_idx","node:Node"),&Skeleton::unbind_child_node_from_bone);
ObjectTypeDB::bind_method(_MD("get_bound_child_nodes_to_bone","bone_idx"),&Skeleton::_get_bound_child_nodes_to_bone);

View File

@ -46,6 +46,7 @@ class Skeleton : public Spatial {
bool enabled;
int parent;
bool disable_rest;
Transform rest;
Transform rest_global_inverse;
@ -57,7 +58,7 @@ class Skeleton : public Spatial {
List<uint32_t> nodes_bound;
Bone() { parent=-1; enabled=true; custom_pose_enable=false; }
Bone() { parent=-1; enabled=true; custom_pose_enable=false; disable_rest=false; }
};
bool rest_global_inverse_dirty;
@ -111,6 +112,11 @@ public:
void set_bone_parent(int p_bone, int p_parent);
int get_bone_parent(int p_bone) const;
void unparent_bone_and_rest(int p_idx);
void set_bone_disable_rest(int p_bone, bool p_disable);
bool is_bone_rest_disabled(int p_bone) const;
int get_bone_count() const;
void set_bone_rest(int p_bone, const Transform& p_rest);

View File

@ -842,6 +842,17 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
boot_splash=splash;
}
}
StringName custom_cursor;
{
String splash=Globals::get_singleton()->get("display/custom_mouse_cursor"); //avoid splash from being converted
splash=splash.strip_edges();
if (splash!=String()) {
if (!splash.begins_with("res://"))
splash="res://"+splash;
splash=splash.simplify_path();
custom_cursor=splash;
}
}
@ -853,7 +864,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
String src=files[i];
Vector<uint8_t> buf;
if (src==boot_splash)
if (src==boot_splash || src==custom_cursor)
buf = get_exported_file_default(src); //bootsplash must be kept if used
else
buf = get_exported_file(src);

View File

@ -93,7 +93,7 @@
#include "plugins/light_occluder_2d_editor_plugin.h"
#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/collision_shape_2d_editor_plugin.h"
#include "os/input.h"
#include "main/input_default.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
@ -4390,11 +4390,15 @@ EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
//only if no touchscreen ui hint, set emulation
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
if (id)
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
if (id) {
if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
//only if no touchscreen ui hint, set emulation
id->set_emulate_touch(false); //just disable just in case
}
id->set_custom_mouse_cursor(RES());
}