diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-06-04 21:31:29 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-06-04 21:31:47 -0300 |
commit | 007efb6a20dcaa9230f1cfdc1cda92db24c5510f (patch) | |
tree | db29be67ba32768ba96037d06c82cb8f1ac7f1c2 /scene | |
parent | 279b7921e8dc8feb44a7650b983f6b3878a01d14 (diff) |
-customizable shortcuts in editor
-editor settings now save to .tres instead of .xml
-buttons can now hold a shortcut
Diffstat (limited to 'scene')
-rw-r--r-- | scene/gui/base_button.cpp | 36 | ||||
-rw-r--r-- | scene/gui/base_button.h | 7 | ||||
-rw-r--r-- | scene/gui/button.cpp | 1 | ||||
-rw-r--r-- | scene/gui/button.h | 4 | ||||
-rw-r--r-- | scene/gui/control.h | 2 | ||||
-rw-r--r-- | scene/gui/input_action.cpp | 125 | ||||
-rw-r--r-- | scene/gui/input_action.h | 26 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 19 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 176 | ||||
-rw-r--r-- | scene/gui/popup_menu.h | 19 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 1 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 1 |
12 files changed, 382 insertions, 35 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 21820d7f10..2200cac5da 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -390,10 +390,43 @@ Control::FocusMode BaseButton::get_enabled_focus_mode() const { return enabled_focus_mode; } +void BaseButton::set_shortcut(const Ref<ShortCut>& p_shortcut) { + + if (shortcut.is_null() == p_shortcut.is_null()) + return; + + shortcut=p_shortcut; + set_process_unhandled_input(shortcut.is_valid()); +} + +Ref<ShortCut> BaseButton:: get_shortcut() const { + return shortcut; +} + +void BaseButton::_unhandled_input(InputEvent p_event) { + + if (!is_disabled() && is_visible() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) { + if (is_toggle_mode()) { + set_pressed(!is_pressed()); + emit_signal("toggled",is_pressed()); + } + + emit_signal("pressed"); + } +} + +String BaseButton::get_tooltip(const Point2& p_pos) const { + + String tooltip=Control::get_tooltip(p_pos); + if (shortcut.is_valid() && shortcut->is_valid()) + tooltip+=" ("+shortcut->get_as_text()+")"; + return tooltip; +} void BaseButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event); + ObjectTypeDB::bind_method(_MD("_unhandled_input"),&BaseButton::_unhandled_input); ObjectTypeDB::bind_method(_MD("set_pressed","pressed"),&BaseButton::set_pressed); ObjectTypeDB::bind_method(_MD("is_pressed"),&BaseButton::is_pressed); ObjectTypeDB::bind_method(_MD("is_hovered"),&BaseButton::is_hovered); @@ -406,6 +439,8 @@ void BaseButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_draw_mode"),&BaseButton::get_draw_mode); ObjectTypeDB::bind_method(_MD("set_enabled_focus_mode","mode"),&BaseButton::set_enabled_focus_mode); ObjectTypeDB::bind_method(_MD("get_enabled_focus_mode"),&BaseButton::get_enabled_focus_mode); + ObjectTypeDB::bind_method(_MD("set_shortcut","shortcut"),&BaseButton::set_shortcut); + ObjectTypeDB::bind_method(_MD("get_shortcut"),&BaseButton::get_shortcut); BIND_VMETHOD(MethodInfo("_pressed")); BIND_VMETHOD(MethodInfo("_toggled",PropertyInfo(Variant::BOOL,"pressed"))); @@ -418,6 +453,7 @@ void BaseButton::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "is_pressed"), _SCS("set_pressed"), _SCS("is_pressed")); ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press")); ADD_PROPERTY( PropertyInfo( Variant::INT,"enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All" ), _SCS("set_enabled_focus_mode"), _SCS("get_enabled_focus_mode") ); + ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "shortcut",PROPERTY_HINT_RESOURCE_TYPE,"ShortCut"), _SCS("set_shortcut"), _SCS("get_shortcut")); BIND_CONSTANT( DRAW_NORMAL ); diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 0247fb2f21..0056b00f33 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -43,6 +43,7 @@ class BaseButton : public Control { bool toggle_mode; FocusMode enabled_focus_mode; + Ref<ShortCut> shortcut; struct Status { @@ -57,6 +58,7 @@ class BaseButton : public Control { } status; + ButtonGroup *group; @@ -69,6 +71,7 @@ protected: virtual void toggled(bool p_pressed); static void _bind_methods(); virtual void _input_event(InputEvent p_event); + virtual void _unhandled_input(InputEvent p_event); void _notification(int p_what); public: @@ -101,6 +104,10 @@ public: void set_enabled_focus_mode(FocusMode p_mode); FocusMode get_enabled_focus_mode() const; + void set_shortcut(const Ref<ShortCut>& p_shortcut); + Ref<ShortCut> get_shortcut() const; + + virtual String get_tooltip(const Point2& p_pos) const; BaseButton(); ~BaseButton(); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 0f1622a838..579f6e08c9 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -213,7 +213,6 @@ Button::TextAlign Button::get_text_align() const { return align; } - void Button::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_text","text"),&Button::set_text); diff --git a/scene/gui/button.h b/scene/gui/button.h index 8a17a164a0..c39237c9af 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -54,7 +54,6 @@ private: TextAlign align; - protected: virtual Size2 get_minimum_size() const; @@ -62,6 +61,8 @@ protected: static void _bind_methods(); public: // + + void set_text(const String& p_text); String get_text() const; @@ -77,6 +78,7 @@ public: void set_text_align(TextAlign p_align); TextAlign get_text_align() const; + Button(const String& p_text=String()); ~Button(); diff --git a/scene/gui/control.h b/scene/gui/control.h index f720185c9d..d77ba27f60 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -35,7 +35,7 @@ #include "scene/2d/canvas_item.h" #include "math_2d.h" #include "rid.h" - +#include "scene/gui/input_action.h" /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/scene/gui/input_action.cpp b/scene/gui/input_action.cpp new file mode 100644 index 0000000000..4cf2661e49 --- /dev/null +++ b/scene/gui/input_action.cpp @@ -0,0 +1,125 @@ +#include "input_action.h" +#include "os/keyboard.h" + +void ShortCut::set_shortcut(const InputEvent& p_shortcut){ + + shortcut=p_shortcut; + emit_changed(); +} + +InputEvent ShortCut::get_shortcut() const{ + + return shortcut; +} + +bool ShortCut::is_shortcut(const InputEvent& p_event) const { + + bool same=false; + + + switch(p_event.type) { + + case InputEvent::KEY: { + + same=(shortcut.key.scancode==p_event.key.scancode && shortcut.key.mod == p_event.key.mod); + + } break; + case InputEvent::JOYSTICK_BUTTON: { + + same=(shortcut.joy_button.button_index==p_event.joy_button.button_index); + + } break; + case InputEvent::MOUSE_BUTTON: { + + same=(shortcut.mouse_button.button_index==p_event.mouse_button.button_index); + + } break; + case InputEvent::JOYSTICK_MOTION: { + + same=(shortcut.joy_motion.axis==p_event.joy_motion.axis && (shortcut.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0)); + + } break; + default: {}; + } + + return same; +} + +String ShortCut::get_as_text() const { + + switch(shortcut.type) { + + case InputEvent::NONE: { + + return "None"; + } break; + case InputEvent::KEY: { + + String str; + if (shortcut.key.mod.shift) + str+=TTR("Shift+"); + if (shortcut.key.mod.alt) + str+=TTR("Alt+"); + if (shortcut.key.mod.control) + str+=TTR("Ctrl+"); + if (shortcut.key.mod.meta) + str+=TTR("Meta+"); + + str+=keycode_get_string(shortcut.key.scancode).capitalize(); + + return str; + } break; + case InputEvent::JOYSTICK_BUTTON: { + + String str = TTR("Device")+" "+itos(shortcut.device)+", "+TTR("Button")+" "+itos(shortcut.joy_button.button_index); + str+="."; + + return str; + } break; + case InputEvent::MOUSE_BUTTON: { + + String str = TTR("Device")+" "+itos(shortcut.device)+", "; + switch (shortcut.mouse_button.button_index) { + case BUTTON_LEFT: str+=TTR("Left Button."); break; + case BUTTON_RIGHT: str+=TTR("Right Button."); break; + case BUTTON_MIDDLE: str+=TTR("Middle Button."); break; + case BUTTON_WHEEL_UP: str+=TTR("Wheel Up."); break; + case BUTTON_WHEEL_DOWN: str+=TTR("Wheel Down."); break; + default: str+=TTR("Button")+" "+itos(shortcut.mouse_button.button_index)+"."; + } + + return str; + } break; + case InputEvent::JOYSTICK_MOTION: { + + int ax = shortcut.joy_motion.axis; + String str = TTR("Device")+" "+itos(shortcut.device)+", "+TTR("Axis")+" "+itos(ax)+"."; + + return str; + } break; + } + + return ""; +} + +bool ShortCut::is_valid() const { + + return shortcut.type!=InputEvent::NONE; +} + +void ShortCut::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_shortcut","event"),&ShortCut::set_shortcut); + ObjectTypeDB::bind_method(_MD("get_shortcut"),&ShortCut::get_shortcut); + + ObjectTypeDB::bind_method(_MD("is_valid"),&ShortCut::is_valid); + + ObjectTypeDB::bind_method(_MD("is_shortcut","event"),&ShortCut::is_shortcut); + ObjectTypeDB::bind_method(_MD("get_as_text"),&ShortCut::get_as_text); + + ADD_PROPERTY(PropertyInfo(Variant::INPUT_EVENT,"shortcut"),_SCS("set_shortcut"),_SCS("get_shortcut")); +} + +ShortCut::ShortCut(){ + +} diff --git a/scene/gui/input_action.h b/scene/gui/input_action.h new file mode 100644 index 0000000000..8e0e1ef0bd --- /dev/null +++ b/scene/gui/input_action.h @@ -0,0 +1,26 @@ +#ifndef INPUTACTION_H +#define INPUTACTION_H + +#include "resource.h" + +class ShortCut : public Resource { + + OBJ_TYPE(ShortCut,Resource); + + InputEvent shortcut; +protected: + + static void _bind_methods(); +public: + + void set_shortcut(const InputEvent& p_shortcut); + InputEvent get_shortcut() const; + bool is_shortcut(const InputEvent& p_Event) const; + bool is_valid() const; + + String get_as_text() const; + + ShortCut(); +}; + +#endif // INPUTACTION_H diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 0e39ee8a76..28d67287d5 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -32,30 +32,15 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) { - //check accelerators - if (p_event.type==InputEvent::KEY && p_event.key.pressed) { + if (p_event.is_pressed() && !p_event.is_echo() && (p_event.type==InputEvent::KEY || p_event.type==InputEvent::ACTION || p_event.type==InputEvent::JOYSTICK_BUTTON)) { if (!get_parent() || !is_visible() || is_disabled()) return; - uint32_t code=p_event.key.scancode; - if (code==0) - code=p_event.key.unicode; - if (p_event.key.mod.control) - code|=KEY_MASK_CTRL; - if (p_event.key.mod.alt) - code|=KEY_MASK_ALT; - if (p_event.key.mod.meta) - code|=KEY_MASK_META; - if (p_event.key.mod.shift) - code|=KEY_MASK_SHIFT; - - - int item = popup->activate_item_by_accelerator(code); + int item = popup->activate_item_by_event(p_event); } - } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 819885809b..4c69584f4a 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -32,9 +32,16 @@ #include "translation.h" #include "os/input.h" -String PopupMenu::_get_accel_text(uint32_t p_accel) const { +String PopupMenu::_get_accel_text(int p_item) const { + + ERR_FAIL_INDEX_V(p_item,items.size(),String()); + + if (items[p_item].shortcut.is_valid()) + return items[p_item].shortcut->get_as_text(); + else if (items[p_item].accel) + return keycode_get_string(items[p_item].accel); + return String(); - return keycode_get_string(p_accel); /* String atxt; if (p_accel&KEY_MASK_SHIFT) @@ -87,14 +94,15 @@ Size2 PopupMenu::get_minimum_size() const { size.width+=check_w+hseparation; } - size.width+=font->get_string_size(items[i].text).width; + String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text; + size.width+=font->get_string_size(text).width; if (i>0) size.height+=vseparation; - if (items[i].accel) { + if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { int accel_w = hseparation*2; - accel_w+=font->get_string_size(_get_accel_text(items[i].accel)).width; + accel_w+=font->get_string_size(_get_accel_text(i)).width; accel_max_w = MAX( accel_w, accel_max_w ); } @@ -484,13 +492,15 @@ void PopupMenu::_notification(int p_what) { } item_ofs.y+=font->get_ascent(); - if (!items[i].separator) - font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),items[i].text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color)); + String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text; + if (!items[i].separator) { + font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color)); + } - if (items[i].accel) { + if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) { //accelerator - String text = _get_accel_text(items[i].accel); + String text = _get_accel_text(i); item_ofs.x=size.width-style->get_margin(MARGIN_RIGHT)-font->get_string_size(text).width; font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,i==mouse_over?font_color_hover:font_color_accel); @@ -570,6 +580,64 @@ void PopupMenu::add_check_item(const String& p_label,int p_ID,uint32_t p_accel) update(); } + +void PopupMenu::add_icon_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID) { + + ERR_FAIL_COND(p_shortcut.is_null()); + + _ref_shortcut(p_shortcut); + + Item item; + item.ID=p_ID; + item.icon=p_icon; + item.shortcut=p_shortcut; + items.push_back(item); + update(); + +} + +void PopupMenu::add_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID){ + + ERR_FAIL_COND(p_shortcut.is_null()); + + _ref_shortcut(p_shortcut); + + Item item; + item.ID=p_ID; + item.shortcut=p_shortcut; + items.push_back(item); + update(); + +} +void PopupMenu::add_icon_check_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID){ + + ERR_FAIL_COND(p_shortcut.is_null()); + + _ref_shortcut(p_shortcut); + + Item item; + item.ID=p_ID; + item.shortcut=p_shortcut; + item.checkable=true; + item.icon=p_icon; + items.push_back(item); + update(); +} + +void PopupMenu::add_check_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID){ + + ERR_FAIL_COND(p_shortcut.is_null()); + + _ref_shortcut(p_shortcut); + + Item item; + item.ID=p_ID; + item.shortcut=p_shortcut; + item.checkable=true; + items.push_back(item); + update(); +} + void PopupMenu::set_item_text(int p_idx,const String& p_text) { ERR_FAIL_INDEX(p_idx,items.size()); @@ -701,6 +769,12 @@ String PopupMenu::get_item_tooltip(int p_idx) const { return items[p_idx].tooltip; } +Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,items.size(),""); + return items[p_idx].shortcut; +} + void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) { ERR_FAIL_INDEX(p_idx,items.size()); @@ -730,6 +804,21 @@ void PopupMenu::set_item_tooltip(int p_idx,const String& p_tooltip) { update(); } +void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut>& p_shortcut) { + ERR_FAIL_INDEX(p_idx,items.size()); + if (items[p_idx].shortcut.is_valid()) { + _unref_shortcut(items[p_idx].shortcut); + } + items[p_idx].shortcut=p_shortcut; + + if (items[p_idx].shortcut.is_valid()) { + _ref_shortcut(items[p_idx].shortcut); + } + + + update(); +} + bool PopupMenu::is_item_checkable(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,items.size(),false); return items[p_idx].checkable; @@ -740,14 +829,36 @@ int PopupMenu::get_item_count() const { return items.size(); } -bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) { +bool PopupMenu::activate_item_by_event(const InputEvent& p_event) { + + uint32_t code=0; + if (p_event.type==InputEvent::KEY) { + code=p_event.key.scancode; + if (code==0) + code=p_event.key.unicode; + if (p_event.key.mod.control) + code|=KEY_MASK_CTRL; + if (p_event.key.mod.alt) + code|=KEY_MASK_ALT; + if (p_event.key.mod.meta) + code|=KEY_MASK_META; + if (p_event.key.mod.shift) + code|=KEY_MASK_SHIFT; + } + int il=items.size(); for(int i=0;i<il;i++) { if (is_item_disabled(i)) continue; - if (items[i].accel==p_accel) { + + if (items[i].shortcut.is_valid() && items[i].shortcut->is_shortcut(p_event)) { + activate_item(i); + return true; + } + + if (code!=0 && items[i].accel==code) { activate_item(i); return true; } @@ -761,7 +872,7 @@ bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) { if(!pm) continue; - if(pm->activate_item_by_accelerator(p_accel)) { + if(pm->activate_item_by_event(p_event)) { return true; } } @@ -791,6 +902,12 @@ void PopupMenu::activate_item(int p_item) { void PopupMenu::remove_item(int p_idx) { + ERR_FAIL_INDEX(p_idx,items.size()); + + if (items[p_idx].shortcut.is_valid()) { + _unref_shortcut(items[p_idx].shortcut); + } + items.remove(p_idx); update(); } @@ -806,6 +923,11 @@ void PopupMenu::add_separator() { void PopupMenu::clear() { + for(int i=0;i<items.size();i++) { + if (items[i].shortcut.is_valid()) { + _unref_shortcut(items[i].shortcut); + } + } items.clear(); mouse_over=-1; update(); @@ -834,6 +956,27 @@ Array PopupMenu::_get_items() const { return items; } + +void PopupMenu::_ref_shortcut( Ref<ShortCut> p_sc) { + + if (!shortcut_refcount.has(p_sc)) { + shortcut_refcount[p_sc]=1; + p_sc->connect("changed",this,"update"); + } else { + shortcut_refcount[p_sc]+=1; + } +} + +void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) { + + ERR_FAIL_COND(!shortcut_refcount.has(p_sc)); + shortcut_refcount[p_sc]--; + if (shortcut_refcount[p_sc]==0) { + p_sc->disconnect("changed",this,"update"); + shortcut_refcount.erase(p_sc); + } +} + void PopupMenu::_set_items(const Array& p_items){ ERR_FAIL_COND(p_items.size() % 10); @@ -912,12 +1055,20 @@ void PopupMenu::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_icon_check_item","texture","label","id","accel"),&PopupMenu::add_icon_check_item,DEFVAL(-1),DEFVAL(0)); ObjectTypeDB::bind_method(_MD("add_check_item","label","id","accel"),&PopupMenu::add_check_item,DEFVAL(-1),DEFVAL(0)); ObjectTypeDB::bind_method(_MD("add_submenu_item","label","submenu","id"),&PopupMenu::add_submenu_item,DEFVAL(-1)); + + ObjectTypeDB::bind_method(_MD("add_icon_shortcut","texture","shortcut:ShortCut","id"),&PopupMenu::add_icon_shortcut,DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("add_shortcut","shortcut:ShortCut","id"),&PopupMenu::add_shortcut,DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("add_icon_check_shortcut","texture","shortcut:ShortCut","id"),&PopupMenu::add_icon_check_shortcut,DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("add_check_shortcut","shortcut:ShortCut","id"),&PopupMenu::add_check_shortcut,DEFVAL(-1)); + + ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&PopupMenu::set_item_text); ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon"),&PopupMenu::set_item_icon); ObjectTypeDB::bind_method(_MD("set_item_accelerator","idx","accel"),&PopupMenu::set_item_accelerator); ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&PopupMenu::set_item_metadata); ObjectTypeDB::bind_method(_MD("set_item_checked","idx","checked"),&PopupMenu::set_item_checked); ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&PopupMenu::set_item_disabled); + ObjectTypeDB::bind_method(_MD("set_item_shortcut","idx","shortcut:ShortCut"),&PopupMenu::set_item_shortcut); ObjectTypeDB::bind_method(_MD("set_item_submenu","idx","submenu"),&PopupMenu::set_item_submenu); ObjectTypeDB::bind_method(_MD("set_item_as_separator","idx","enable"),&PopupMenu::set_item_as_separator); ObjectTypeDB::bind_method(_MD("set_item_as_checkable","idx","enable"),&PopupMenu::set_item_as_checkable); @@ -926,6 +1077,7 @@ void PopupMenu::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_item_icon","idx"),&PopupMenu::get_item_icon); ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&PopupMenu::get_item_metadata); ObjectTypeDB::bind_method(_MD("get_item_accelerator","idx"),&PopupMenu::get_item_accelerator); + ObjectTypeDB::bind_method(_MD("get_item_shortcut:ShortCut","idx"),&PopupMenu::get_item_shortcut); ObjectTypeDB::bind_method(_MD("get_item_submenu","idx"),&PopupMenu::get_item_submenu); ObjectTypeDB::bind_method(_MD("is_item_separator","idx"),&PopupMenu::is_item_separator); ObjectTypeDB::bind_method(_MD("is_item_checkable","idx"),&PopupMenu::is_item_checkable); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 0e98765dc4..f35e91d4e4 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -34,6 +34,9 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ + + + class PopupMenu : public Popup { OBJ_TYPE(PopupMenu, Popup ); @@ -51,6 +54,7 @@ class PopupMenu : public Popup { String tooltip; uint32_t accel; int _ofs_cache; + Ref<ShortCut> shortcut; Item() { checked=false; checkable=false; separator=false; accel=0; disabled=false; _ofs_cache=0; } }; @@ -62,7 +66,7 @@ class PopupMenu : public Popup { int mouse_over; int submenu_over; Rect2 parent_rect; - String _get_accel_text(uint32_t p_accel) const; + String _get_accel_text(int p_item) const; int _get_mouse_over(const Point2& p_over) const; virtual Size2 get_minimum_size() const; void _input_event(const InputEvent &p_event); @@ -75,6 +79,10 @@ class PopupMenu : public Popup { Array _get_items() const; void _set_items(const Array& p_items); + Map< Ref<ShortCut>, int> shortcut_refcount; + + void _ref_shortcut(Ref<ShortCut> p_sc); + void _unref_shortcut( Ref<ShortCut> p_sc); protected: virtual bool has_point(const Point2& p_point) const; @@ -90,6 +98,11 @@ public: void add_check_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0); void add_submenu_item(const String& p_label,const String& p_submenu, int p_ID=-1); + void add_icon_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID=-1); + void add_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID=-1); + void add_icon_check_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID=-1); + void add_check_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID=-1); + void set_item_text(int p_idx,const String& p_text); void set_item_icon(int p_idx,const Ref<Texture>& p_icon); void set_item_checked(int p_idx,bool p_checked); @@ -101,6 +114,7 @@ public: void set_item_as_separator(int p_idx, bool p_separator); void set_item_as_checkable(int p_idx, bool p_checkable); void set_item_tooltip(int p_idx,const String& p_tooltip); + void set_item_shortcut(int p_idx, const Ref<ShortCut>& p_shortcut); String get_item_text(int p_idx) const; Ref<Texture> get_item_icon(int p_idx) const; @@ -114,10 +128,11 @@ public: bool is_item_separator(int p_idx) const; bool is_item_checkable(int p_idx) const; String get_item_tooltip(int p_idx) const; + Ref<ShortCut> get_item_shortcut(int p_idx) const; int get_item_count() const; - bool activate_item_by_accelerator(uint32_t p_accel); + bool activate_item_by_event(const InputEvent& p_event); void activate_item(int p_item); void remove_item(int p_idx); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5ce53194a1..313be88526 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1358,7 +1358,6 @@ void Viewport::_vp_unhandled_input(const InputEvent& p_ev) { if (disable_input) return; - #ifdef TOOLS_ENABLED if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { return; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 1fd1c77dca..ed38379ca9 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -293,6 +293,7 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init + ObjectTypeDB::register_type<ShortCut>(); ObjectTypeDB::register_type<Control>(); // ObjectTypeDB::register_type<EmptyControl>(); ObjectTypeDB::add_compatibility_type("EmptyControl","Control"); |