From d4051e6eb91ecad424a0c1d4438d99fbe622cbe3 Mon Sep 17 00:00:00 2001 From: neikeq Date: Tue, 8 Dec 2015 19:04:56 +0100 Subject: [PATCH] Spinbox: increase/decrease with mouse held --- scene/gui/spin_box.cpp | 31 +++++++++++++++++++++ scene/gui/spin_box.h | 4 +++ scene/gui/tree.cpp | 62 +++++++++++++++++++++++++++++++++++++++++- scene/gui/tree.h | 7 ++++- 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index a48136f541e..051a8dd0181 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -68,6 +68,25 @@ void SpinBox::_line_edit_input(const InputEvent& p_event) { } +void SpinBox::_range_click_timeout() { + + if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + + int pos_y = Input::get_singleton()->get_mouse_pos().y-get_global_pos().y; + bool up = pos_y < (get_size().height/2); + set_val( get_val() + (up?get_step():-get_step())); + + if (range_click_timer->is_one_shot()) { + range_click_timer->set_wait_time(0.075); + range_click_timer->set_one_shot(false); + range_click_timer->start(); + } + + } else { + range_click_timer->stop(); + } +} + void SpinBox::_input_event(const InputEvent& p_event) { @@ -85,6 +104,10 @@ void SpinBox::_input_event(const InputEvent& p_event) { set_val( get_val() + (up?get_step():-get_step())); + range_click_timer->set_wait_time(0.6); + range_click_timer->set_one_shot(true); + range_click_timer->start(); + } break; case BUTTON_RIGHT: { @@ -112,6 +135,8 @@ void SpinBox::_input_event(const InputEvent& p_event) { 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); + range_click_timer->stop(); + if (drag.enabled) { drag.enabled=false; Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); @@ -167,6 +192,7 @@ void SpinBox::_notification(int p_what) { Size2i size = get_size(); updown->draw(ci,Point2i(size.width-updown->get_width(),(size.height-updown->get_height())/2)); + } else if (p_what==NOTIFICATION_FOCUS_EXIT) { @@ -227,6 +253,7 @@ void SpinBox::_bind_methods() { 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); + ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&SpinBox::_range_click_timeout); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable")); @@ -248,4 +275,8 @@ SpinBox::SpinBox() { line_edit->connect("focus_exit",this,"_line_edit_focus_exit",Vector(),CONNECT_DEFERRED); line_edit->connect("input_event",this,"_line_edit_input"); drag.enabled=false; + + range_click_timer = memnew( Timer ); + range_click_timer->connect("timeout",this,"_range_click_timeout"); + add_child(range_click_timer); } diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 4c8cb8432a2..1b3bc6d8170 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -31,6 +31,7 @@ #include "scene/gui/line_edit.h" #include "scene/gui/range.h" +#include "scene/main/timer.h" class SpinBox : public Range { @@ -39,6 +40,9 @@ class SpinBox : public Range { LineEdit *line_edit; int last_w; + Timer *range_click_timer; + void _range_click_timeout(); + void _text_entered(const String& p_string); virtual void _value_changed(double); String prefix; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 16a12fe4077..ee7c0724e3b 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1369,7 +1369,40 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { } +void Tree::_range_click_timeout() { + if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + + Point2 pos = (Input::get_singleton()->get_mouse_pos()-get_global_pos())-cache.bg->get_offset(); + if (show_column_titles) { + pos.y-=_get_title_button_height(); + + if (pos.y<0) { + range_click_timer->stop(); + return; + } + } + + click_handled=false; + InputModifierState mod = {}; // should be irrelevant.. + + blocked++; + propagate_mouse_event(pos+cache.offset, 0, 0, false, root, BUTTON_LEFT, mod); + blocked--; + + if (range_click_timer->is_one_shot()) { + range_click_timer->set_wait_time(0.05); + range_click_timer->set_one_shot(false); + range_click_timer->start(); + } + + if (!click_handled) + range_click_timer->stop(); + + } else { + range_click_timer->stop(); + } +} int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_doubleclick,TreeItem *p_item,int p_button,const InputModifierState& p_mod) { @@ -1564,9 +1597,25 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ bool up=p_pos.y < (item_h /2); if (p_button==BUTTON_LEFT) { + + if (range_click_timer->get_time_left() == 0) { + + range_item_last=p_item; + range_up_last=up; + + range_click_timer->set_wait_time(0.6); + range_click_timer->set_one_shot(true); + range_click_timer->start(); + + } else if (up != range_up_last) { + + return -1; // break. avoid changing direction on mouse held + } + p_item->set_range( col, c.val + (up?1.0:-1.0) * c.step ); item_edited(col,p_item); + } else if (p_button==BUTTON_RIGHT) { p_item->set_range( col, (up?c.max:c.min) ); @@ -2024,6 +2073,8 @@ void Tree::_input_event(InputEvent p_event) { update_cache(); const InputEventMouseMotion& b=p_event.mouse_motion; + range_click_timer->stop(); + Ref bg = cache.bg; Point2 pos = Point2(b.x,b.y) - bg->get_offset(); @@ -2031,7 +2082,6 @@ void Tree::_input_event(InputEvent p_event) { Cache::ClickType old_hover = cache.hover_type; int old_index = cache.hover_index; - cache.hover_type=Cache::CLICK_NONE; cache.hover_index=0; if (show_column_titles) { @@ -2108,6 +2158,8 @@ void Tree::_input_event(InputEvent p_event) { if (b.button_index==BUTTON_LEFT) { + range_click_timer->stop(); + if (pressing_for_editor) { if (range_drag_enabled) { @@ -2228,10 +2280,13 @@ void Tree::_input_event(InputEvent p_event) { } break; case BUTTON_WHEEL_UP: { + + range_click_timer->stop(); v_scroll->set_val( v_scroll->get_val()-v_scroll->get_page()/8 ); } break; case BUTTON_WHEEL_DOWN: { + range_click_timer->stop(); v_scroll->set_val( v_scroll->get_val()+v_scroll->get_page()/8 ); } break; } @@ -3135,6 +3190,7 @@ bool Tree::is_folding_hidden() const { void Tree::_bind_methods() { + ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&Tree::_range_click_timeout); ObjectTypeDB::bind_method(_MD("_input_event"),&Tree::_input_event); ObjectTypeDB::bind_method(_MD("_popup_select"),&Tree::popup_select); ObjectTypeDB::bind_method(_MD("_text_editor_enter"),&Tree::text_editor_enter); @@ -3229,6 +3285,10 @@ Tree::Tree() { add_child(h_scroll); add_child(v_scroll); + range_click_timer = memnew( Timer ); + range_click_timer->connect("timeout",this,"_range_click_timeout"); + add_child(range_click_timer); + h_scroll->connect("value_changed", this,"_scroll_moved"); v_scroll->connect("value_changed", this,"_scroll_moved"); text_editor->connect("text_entered", this,"_text_editor_enter"); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 8fb9b802a1f..55ccc16d017 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -127,7 +127,7 @@ friend class Tree; - TreeItem(Tree *p_tree); + TreeItem(Tree *p_tree); void _changed_notify(int p_cell); @@ -301,6 +301,11 @@ friend class TreeItem; Vector columns; + Timer *range_click_timer; + TreeItem *range_item_last; + bool range_up_last; + void _range_click_timeout(); + int compute_item_height(TreeItem *p_item) const; int get_item_height(TreeItem *p_item) const; // void draw_item_text(String p_text,const Ref& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color);