-fixes to capture mode
-ability to drag spinboxes and tree ranges to change values, like in Unity or Unreal
This commit is contained in:
parent
b0be30d9ef
commit
3a59747c62
6 changed files with 204 additions and 29 deletions
|
@ -504,6 +504,23 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
|
|||
mouse_mode=p_mode;
|
||||
|
||||
if (mouse_mode==MOUSE_MODE_CAPTURED) {
|
||||
|
||||
while(true) {
|
||||
//flush pending motion events
|
||||
|
||||
if (XPending(x11_display) > 0) {
|
||||
XEvent event;
|
||||
XPeekEvent(x11_display, &event);
|
||||
if (event.type==MotionNotify) {
|
||||
XNextEvent(x11_display,&event);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (XGrabPointer(x11_display, x11_window, True,
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask, GrabModeAsync, GrabModeAsync,
|
||||
|
@ -518,6 +535,8 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
|
|||
0,0,0,0, (int)center.x, (int)center.y);
|
||||
|
||||
input->set_mouse_pos(center);
|
||||
} else {
|
||||
do_mouse_warp=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1131,7 +1150,7 @@ void OS_X11::process_xevents() {
|
|||
|
||||
//printf("checking events %i\n", XPending(x11_display));
|
||||
|
||||
bool do_mouse_warp=false;
|
||||
do_mouse_warp=false;
|
||||
|
||||
while (XPending(x11_display) > 0) {
|
||||
XEvent event;
|
||||
|
@ -1244,8 +1263,38 @@ void OS_X11::process_xevents() {
|
|||
|
||||
} break;
|
||||
case MotionNotify: {
|
||||
|
||||
|
||||
// FUCK YOU X11 API YOU SERIOUSLY GROSS ME OUT
|
||||
// YOU ARE AS GROSS AS LOOKING AT A PUTRID PILE
|
||||
// OF POOP STICKING OUT OF A CLOGGED TOILET
|
||||
// HOW THE FUCK I AM SUPPOSED TO KNOW WHICH ONE
|
||||
// OF THE MOTION NOTIFY EVENTS IS THE ONE GENERATED
|
||||
// BY WARPING THE MOUSE POINTER?
|
||||
// YOU ARE FORCING ME TO FILTER ONE BY ONE TO FIND IT
|
||||
// PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL
|
||||
// MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG.
|
||||
|
||||
|
||||
while(true) {
|
||||
if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) {
|
||||
//this is likely the warp event since it was warped here
|
||||
center=Vector2(event.xmotion.x,event.xmotion.y);
|
||||
break;
|
||||
}
|
||||
|
||||
if (XPending(x11_display) > 0) {
|
||||
XEvent tevent;
|
||||
XPeekEvent(x11_display, &tevent);
|
||||
if (tevent.type==MotionNotify) {
|
||||
XNextEvent(x11_display,&event);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last_timestamp=event.xmotion.time;
|
||||
|
||||
// Motion is also simple.
|
||||
|
|
|
@ -114,6 +114,7 @@ class OS_X11 : public OS_Unix {
|
|||
bool minimized;
|
||||
int dpad_last[2];
|
||||
|
||||
bool do_mouse_warp;
|
||||
|
||||
const char *cursor_theme;
|
||||
int cursor_size;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "spin_box.h"
|
||||
|
||||
#include "os/input.h"
|
||||
|
||||
Size2 SpinBox::get_minimum_size() const {
|
||||
|
||||
|
@ -62,6 +62,13 @@ LineEdit *SpinBox::get_line_edit() {
|
|||
}
|
||||
|
||||
|
||||
void SpinBox::_line_edit_input(const InputEvent& p_event) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SpinBox::_input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed) {
|
||||
|
@ -94,6 +101,48 @@ void SpinBox::_input_event(const InputEvent& p_event) {
|
|||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
|
||||
|
||||
//set_default_cursor_shape(CURSOR_VSIZE);
|
||||
Vector2 cpos = Vector2(p_event.mouse_button.x,p_event.mouse_button.y);
|
||||
drag.mouse_pos=cpos;
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
|
||||
|
||||
//set_default_cursor_shape(CURSOR_ARROW);
|
||||
if (drag.enabled) {
|
||||
drag.enabled=false;
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
||||
warp_mouse(drag.capture_pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_button.button_mask&1) {
|
||||
|
||||
Vector2 cpos = Vector2(p_event.mouse_motion.x,p_event.mouse_motion.y);
|
||||
if (drag.enabled) {
|
||||
|
||||
float diff_y = drag.mouse_pos.y - cpos.y;
|
||||
diff_y=pow(ABS(diff_y),1.8)*SGN(diff_y);
|
||||
diff_y*=0.1;
|
||||
|
||||
drag.mouse_pos=cpos;
|
||||
drag.base_val=CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max());
|
||||
|
||||
set_val( drag.base_val);
|
||||
|
||||
} else if (drag.mouse_pos.distance_to(cpos)>2) {
|
||||
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
|
||||
drag.enabled=true;
|
||||
drag.base_val=get_val();
|
||||
drag.mouse_pos=cpos;
|
||||
drag.capture_pos=cpos;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,6 +226,7 @@ void SpinBox::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("is_editable"),&SpinBox::is_editable);
|
||||
ObjectTypeDB::bind_method(_MD("_line_edit_focus_exit"),&SpinBox::_line_edit_focus_exit);
|
||||
ObjectTypeDB::bind_method(_MD("get_line_edit"),&SpinBox::get_line_edit);
|
||||
ObjectTypeDB::bind_method(_MD("_line_edit_input"),&SpinBox::_line_edit_input);
|
||||
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable"));
|
||||
|
@ -196,4 +246,6 @@ SpinBox::SpinBox() {
|
|||
//connect("value_changed",this,"_value_changed");
|
||||
line_edit->connect("text_entered",this,"_text_entered",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
line_edit->connect("focus_exit",this,"_line_edit_focus_exit",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
line_edit->connect("input_event",this,"_line_edit_input");
|
||||
drag.enabled=false;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,18 @@ class SpinBox : public Range {
|
|||
String prefix;
|
||||
String suffix;
|
||||
|
||||
void _line_edit_input(const InputEvent& p_event);
|
||||
|
||||
|
||||
struct Drag {
|
||||
float base_val;
|
||||
bool enabled;
|
||||
Vector2 from;
|
||||
Vector2 mouse_pos;
|
||||
Vector2 capture_pos;
|
||||
} drag;
|
||||
|
||||
|
||||
void _line_edit_focus_exit();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "os/os.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "globals.h"
|
||||
|
||||
#include "os/input.h"
|
||||
|
||||
|
||||
|
||||
|
@ -70,6 +70,7 @@ Size2 TreeItem::Cell::get_icon_size() const {
|
|||
else
|
||||
return icon_region.size;
|
||||
}
|
||||
|
||||
void TreeItem::Cell::draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size) const{
|
||||
|
||||
if (icon.is_null())
|
||||
|
@ -728,14 +729,20 @@ TreeItem::~TreeItem() {
|
|||
tree->root=0;
|
||||
}
|
||||
|
||||
if (tree && tree->popup_edited_item==this)
|
||||
if (tree && tree->popup_edited_item==this) {
|
||||
tree->popup_edited_item=NULL;
|
||||
tree->pressing_for_editor=false;
|
||||
|
||||
}
|
||||
|
||||
if (tree && tree->selected_item==this)
|
||||
tree->selected_item=NULL;
|
||||
|
||||
if (tree && tree->edited_item==this)
|
||||
if (tree && tree->edited_item==this) {
|
||||
tree->edited_item=NULL;
|
||||
tree->pressing_for_editor=false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1490,7 +1497,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
|
|||
|
||||
/* editing */
|
||||
|
||||
bool bring_up_editor=c.selected && already_selected;
|
||||
bool bring_up_editor=c.selected;// && already_selected;
|
||||
bool bring_up_value_editor=false;
|
||||
String editor_text=c.text;
|
||||
|
||||
|
@ -1605,31 +1612,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
|
|||
return -1;
|
||||
|
||||
|
||||
click_handled=true;
|
||||
|
||||
click_handled=true;
|
||||
popup_edited_item=p_item;
|
||||
popup_edited_item_col=col;
|
||||
text_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset );
|
||||
text_editor->set_size( Size2(col_width,item_h));
|
||||
text_editor->clear();
|
||||
text_editor->set_text( editor_text );
|
||||
text_editor->select_all();
|
||||
|
||||
if (bring_up_value_editor) {
|
||||
|
||||
value_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset+Point2i(0,text_editor->get_size().height) );
|
||||
value_editor->set_size( Size2(col_width,1));
|
||||
value_editor->show_modal();
|
||||
updating_value_editor=true;
|
||||
value_editor->set_min( c.min );
|
||||
value_editor->set_max( c.max );
|
||||
value_editor->set_step( c.step );
|
||||
value_editor->set_val( c.val );
|
||||
value_editor->set_exp_unit_value( c.expr );
|
||||
updating_value_editor=false;
|
||||
}
|
||||
|
||||
text_editor->show_modal();
|
||||
text_editor->grab_focus();
|
||||
pressing_item_rect=Rect2(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset,Size2(col_width,item_h));
|
||||
pressing_for_editor_text=editor_text;
|
||||
pressing_for_editor=true;
|
||||
|
||||
return -1; //select
|
||||
} else {
|
||||
|
@ -2062,6 +2052,33 @@ void Tree::_input_event(InputEvent p_event) {
|
|||
update();
|
||||
}
|
||||
|
||||
if (pressing_for_editor && popup_edited_item && popup_edited_item->get_cell_mode(popup_edited_item_col)==TreeItem::CELL_MODE_RANGE) {
|
||||
//range drag
|
||||
|
||||
if (!range_drag_enabled) {
|
||||
|
||||
Vector2 cpos = Vector2(b.x,b.y);
|
||||
if (cpos.distance_to(pressing_pos)>2) {
|
||||
range_drag_enabled=true;
|
||||
range_drag_capture_pos=cpos;
|
||||
range_drag_base=popup_edited_item->get_range(popup_edited_item_col);
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
|
||||
}
|
||||
} else {
|
||||
|
||||
TreeItem::Cell &c=popup_edited_item->cells[popup_edited_item_col];
|
||||
float diff_y = -b.relative_y;
|
||||
diff_y=pow(ABS(diff_y),1.8)*SGN(diff_y);
|
||||
diff_y*=0.1;
|
||||
range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
|
||||
|
||||
popup_edited_item->set_range(popup_edited_item_col,range_drag_base);
|
||||
item_edited(popup_edited_item_col,popup_edited_item);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (drag_touching && ! drag_touching_deaccel) {
|
||||
|
||||
|
||||
|
@ -2084,6 +2101,31 @@ void Tree::_input_event(InputEvent p_event) {
|
|||
|
||||
if (b.button_index==BUTTON_LEFT) {
|
||||
|
||||
if (pressing_for_editor) {
|
||||
|
||||
if (range_drag_enabled) {
|
||||
|
||||
range_drag_enabled=false;
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
||||
warp_mouse(range_drag_capture_pos);
|
||||
} else {
|
||||
text_editor->set_pos(pressing_item_rect.pos);
|
||||
text_editor->set_size(pressing_item_rect.size);
|
||||
|
||||
text_editor->clear();
|
||||
text_editor->set_text( pressing_for_editor_text );
|
||||
text_editor->select_all();
|
||||
|
||||
text_editor->show_modal();
|
||||
text_editor->grab_focus();
|
||||
|
||||
}
|
||||
pressing_for_editor=false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (cache.click_type==Cache::CLICK_BUTTON) {
|
||||
emit_signal("button_pressed",cache.click_item,cache.click_column,cache.click_id);
|
||||
|
||||
|
@ -2145,11 +2187,15 @@ void Tree::_input_event(InputEvent p_event) {
|
|||
break;
|
||||
|
||||
click_handled=false;
|
||||
pressing_for_editor=false;
|
||||
|
||||
blocked++;
|
||||
bool handled = propagate_mouse_event(pos+cache.offset,0,0,b.doubleclick,root,b.button_index,b.mod);
|
||||
blocked--;
|
||||
|
||||
if (pressing_for_editor) {
|
||||
pressing_pos=Point2(b.x,b.y);
|
||||
}
|
||||
|
||||
|
||||
if (drag_touching) {
|
||||
|
@ -2615,6 +2661,8 @@ void Tree::clear() {
|
|||
selected_item=NULL;
|
||||
edited_item=NULL;
|
||||
popup_edited_item=NULL;
|
||||
selected_item=NULL;
|
||||
pressing_for_editor=false;
|
||||
|
||||
update();
|
||||
};
|
||||
|
@ -3189,6 +3237,8 @@ Tree::Tree() {
|
|||
drag_speed=0;
|
||||
drag_touching=false;
|
||||
drag_touching_deaccel=false;
|
||||
pressing_for_editor=false;
|
||||
range_drag_enabled=false;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -258,7 +258,18 @@ friend class TreeItem;
|
|||
TreeItem *popup_edited_item;
|
||||
TreeItem *selected_item;
|
||||
TreeItem *edited_item;
|
||||
|
||||
|
||||
int pressed_button;
|
||||
bool pressing_for_editor;
|
||||
String pressing_for_editor_text;
|
||||
Vector2 pressing_pos;
|
||||
Rect2 pressing_item_rect;
|
||||
|
||||
float range_drag_base;
|
||||
bool range_drag_enabled;
|
||||
Vector2 range_drag_capture_pos;
|
||||
|
||||
|
||||
//TreeItem *cursor_item;
|
||||
//int cursor_column;
|
||||
|
|
Loading…
Reference in a new issue