Преглед на файлове

-fixes to capture mode
-ability to drag spinboxes and tree ranges to change values, like in Unity or Unreal

Juan Linietsky преди 10 години
родител
ревизия
3a59747c62
променени са 6 файла, в които са добавени 204 реда и са изтрити 29 реда
  1. 51 2
      platform/x11/os_x11.cpp
  2. 1 0
      platform/x11/os_x11.h
  3. 53 1
      scene/gui/spin_box.cpp
  4. 12 0
      scene/gui/spin_box.h
  5. 76 26
      scene/gui/tree.cpp
  6. 11 0
      scene/gui/tree.h

+ 51 - 2
platform/x11/os_x11.cpp

@@ -504,6 +504,23 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
 	mouse_mode=p_mode;
 	mouse_mode=p_mode;
 
 
 	if (mouse_mode==MOUSE_MODE_CAPTURED) {
 	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,
 		if (XGrabPointer(x11_display, x11_window, True,
 				    ButtonPressMask | ButtonReleaseMask |
 				    ButtonPressMask | ButtonReleaseMask |
 				    PointerMotionMask, GrabModeAsync, GrabModeAsync,
 				    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);
 			      0,0,0,0, (int)center.x, (int)center.y);
 
 
 		input->set_mouse_pos(center);
 		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));
 	//printf("checking events %i\n", XPending(x11_display));
 
 
-	bool do_mouse_warp=false;
+	do_mouse_warp=false;
 
 
 	while (XPending(x11_display) > 0) {
 	while (XPending(x11_display) > 0) {
 		XEvent event;
 		XEvent event;
@@ -1244,8 +1263,38 @@ void OS_X11::process_xevents() {
 			
 			
 		} break;	
 		} break;	
 		case MotionNotify: {
 		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;
 			last_timestamp=event.xmotion.time;
 		
 		
 			// Motion is also simple.
 			// Motion is also simple.

+ 1 - 0
platform/x11/os_x11.h

@@ -114,6 +114,7 @@ class OS_X11 : public OS_Unix {
 	bool minimized;
 	bool minimized;
 	int dpad_last[2];
 	int dpad_last[2];
 
 
+	bool do_mouse_warp;
 
 
 	const char *cursor_theme;
 	const char *cursor_theme;
 	int cursor_size;
 	int cursor_size;

+ 53 - 1
scene/gui/spin_box.cpp

@@ -27,7 +27,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 /*************************************************************************/
 #include "spin_box.h"
 #include "spin_box.h"
-
+#include "os/input.h"
 
 
 Size2 SpinBox::get_minimum_size() const {
 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) {
 void SpinBox::_input_event(const InputEvent& p_event) {
 
 
 	if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed) {
 	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;
 			} 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("is_editable"),&SpinBox::is_editable);
 	ObjectTypeDB::bind_method(_MD("_line_edit_focus_exit"),&SpinBox::_line_edit_focus_exit);
 	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("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"));
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable"));
@@ -196,4 +246,6 @@ SpinBox::SpinBox() {
 	//connect("value_changed",this,"_value_changed");
 	//connect("value_changed",this,"_value_changed");
 	line_edit->connect("text_entered",this,"_text_entered",Vector<Variant>(),CONNECT_DEFERRED);
 	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("focus_exit",this,"_line_edit_focus_exit",Vector<Variant>(),CONNECT_DEFERRED);
+	line_edit->connect("input_event",this,"_line_edit_input");
+	drag.enabled=false;
 }
 }

+ 12 - 0
scene/gui/spin_box.h

@@ -44,6 +44,18 @@ class SpinBox : public Range {
 	String prefix;
 	String prefix;
 	String suffix;
 	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();
 	void _line_edit_focus_exit();
 
 
 protected:
 protected:

+ 76 - 26
scene/gui/tree.cpp

@@ -31,7 +31,7 @@
 #include "os/os.h"
 #include "os/os.h"
 #include "os/keyboard.h"
 #include "os/keyboard.h"
 #include "globals.h"
 #include "globals.h"
-
+#include "os/input.h"
 
 
 
 
 
 
@@ -70,6 +70,7 @@ Size2 TreeItem::Cell::get_icon_size() const {
 	else
 	else
 		return icon_region.size;
 		return icon_region.size;
 }
 }
+
 void TreeItem::Cell::draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size) const{
 void TreeItem::Cell::draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size) const{
 
 
 	if (icon.is_null())
 	if (icon.is_null())
@@ -728,14 +729,20 @@ TreeItem::~TreeItem() {
 		tree->root=0;
 		tree->root=0;
 	}
 	}
 
 
-	if (tree && tree->popup_edited_item==this)
+	if (tree && tree->popup_edited_item==this) {
 		tree->popup_edited_item=NULL;
 		tree->popup_edited_item=NULL;
+		tree->pressing_for_editor=false;
+
+	}
 
 
 	if (tree && tree->selected_item==this)
 	if (tree && tree->selected_item==this)
 		tree->selected_item=NULL;
 		tree->selected_item=NULL;
 
 
-	if (tree && tree->edited_item==this)
+	if (tree && tree->edited_item==this) {
 		tree->edited_item=NULL;
 		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 */
 		/* editing */
 
 
-		bool bring_up_editor=c.selected && already_selected;
+		bool bring_up_editor=c.selected;// && already_selected;
 		bool bring_up_value_editor=false;
 		bool bring_up_value_editor=false;
 		String editor_text=c.text;
 		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;
 			return -1;
 
 
 
 
-		click_handled=true;
+
+		click_handled=true;		
 		popup_edited_item=p_item;
 		popup_edited_item=p_item;
 		popup_edited_item_col=col;
 		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
 		return -1; //select
 	} else {
 	} else {
@@ -2062,6 +2052,33 @@ void Tree::_input_event(InputEvent p_event) {
 				update();
 				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) {
 			if (drag_touching && ! drag_touching_deaccel) {
 
 
 
 
@@ -2084,6 +2101,31 @@ void Tree::_input_event(InputEvent p_event) {
 
 
 				if (b.button_index==BUTTON_LEFT) {
 				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) {
 					if (cache.click_type==Cache::CLICK_BUTTON) {
 						emit_signal("button_pressed",cache.click_item,cache.click_column,cache.click_id);
 						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;
 						break;
 
 
 					click_handled=false;
 					click_handled=false;
+					pressing_for_editor=false;
 
 
 					blocked++;
 					blocked++;
 					bool handled = propagate_mouse_event(pos+cache.offset,0,0,b.doubleclick,root,b.button_index,b.mod);
 					bool handled = propagate_mouse_event(pos+cache.offset,0,0,b.doubleclick,root,b.button_index,b.mod);
 					blocked--;
 					blocked--;
 
 
+					if (pressing_for_editor) {
+						pressing_pos=Point2(b.x,b.y);
+					}
 
 
 
 
 					if (drag_touching) {
 					if (drag_touching) {
@@ -2615,6 +2661,8 @@ void Tree::clear() {
 	selected_item=NULL;
 	selected_item=NULL;
 	edited_item=NULL;
 	edited_item=NULL;
 	popup_edited_item=NULL;
 	popup_edited_item=NULL;
+	selected_item=NULL;
+	pressing_for_editor=false;
 
 
 	update();
 	update();
 };
 };
@@ -3189,6 +3237,8 @@ Tree::Tree() {
 	drag_speed=0;
 	drag_speed=0;
 	drag_touching=false;
 	drag_touching=false;
 	drag_touching_deaccel=false;
 	drag_touching_deaccel=false;
+	pressing_for_editor=false;
+	range_drag_enabled=false;
 
 
 }
 }
 
 

+ 11 - 0
scene/gui/tree.h

@@ -258,7 +258,18 @@ friend class TreeItem;
 	TreeItem *popup_edited_item;
 	TreeItem *popup_edited_item;
 	TreeItem *selected_item;
 	TreeItem *selected_item;
 	TreeItem *edited_item;
 	TreeItem *edited_item;
+
+
 	int pressed_button;
 	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;
 	//TreeItem *cursor_item;
 	//int cursor_column;
 	//int cursor_column;