1 /* 2 * Copyright (C) 2010-2019 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2017 Robin Gareus <robin@gareus.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef __libgtkmm2ext_bindings_h__ 21 #define __libgtkmm2ext_bindings_h__ 22 23 #include <map> 24 #include <vector> 25 #include <list> 26 27 #include <stdint.h> 28 29 #include <gdk/gdkkeysyms.h> 30 #include <gtkmm/action.h> 31 #include <gtkmm/radioaction.h> 32 #include <gtkmm/toggleaction.h> 33 34 #include "pbd/signals.h" 35 36 #include "gtkmm2ext/visibility.h" 37 38 class XMLNode; 39 class XMLProperty; 40 41 namespace Gtkmm2ext { 42 43 class LIBGTKMM2EXT_API KeyboardKey 44 { 45 public: KeyboardKey()46 KeyboardKey () { 47 _val = GDK_VoidSymbol; 48 } 49 50 KeyboardKey (uint32_t state, uint32_t keycode); 51 null_key()52 static KeyboardKey null_key() { return KeyboardKey (0, 0); } 53 state()54 uint32_t state() const { return _val >> 32; } key()55 uint32_t key() const { return _val & 0xffffffff; } 56 57 bool operator<(const KeyboardKey& other) const { 58 return _val < other._val; 59 } 60 61 bool operator==(const KeyboardKey& other) const { 62 return _val == other._val; 63 } 64 65 std::string name() const; 66 std::string native_name() const; 67 std::string native_short_name() const; 68 static bool make_key (const std::string&, KeyboardKey&); 69 70 std::string display_label() const; 71 72 private: 73 uint64_t _val; 74 }; 75 76 class LIBGTKMM2EXT_API MouseButton { 77 public: MouseButton()78 MouseButton () { 79 _val = ~0ULL; 80 } 81 82 MouseButton (uint32_t state, uint32_t button_number); state()83 uint32_t state() const { return _val >> 32; } button()84 uint32_t button() const { return _val & 0xffff; } 85 86 bool operator<(const MouseButton& other) const { 87 return _val < other._val; 88 } 89 90 bool operator==(const MouseButton& other) const { 91 return _val == other._val; 92 } 93 94 std::string name() const; 95 static bool make_button (const std::string&, MouseButton&); 96 97 private: 98 uint64_t _val; 99 }; 100 101 class LIBGTKMM2EXT_API Bindings; 102 103 class LIBGTKMM2EXT_API Bindings { 104 public: 105 enum Operation { 106 Press, 107 Release 108 }; 109 110 struct ActionInfo { ActionInfoActionInfo111 ActionInfo (std::string const& name) : action_name (name) {} ActionInfoActionInfo112 ActionInfo (std::string const& name, std::string const& grp) : action_name (name), group_name (grp) {} 113 114 std::string action_name; 115 std::string group_name; /* may be empty */ 116 mutable Glib::RefPtr<Gtk::Action> action; 117 }; 118 typedef std::map<KeyboardKey,ActionInfo> KeybindingMap; 119 120 Bindings (std::string const& name); 121 ~Bindings (); 122 name()123 std::string const& name() const { return _name; } 124 125 void reassociate (); 126 void associate (); 127 void dissociate (); 128 129 bool empty() const; 130 bool empty_keys () const; 131 bool empty_mouse () const; 132 133 bool add (KeyboardKey, Operation, std::string const&, XMLProperty const*, bool can_save = false); 134 bool replace (KeyboardKey, Operation, std::string const& action_name, bool can_save = true); 135 bool remove (Operation, std::string const& action_name, bool can_save = false); 136 137 bool activate (KeyboardKey, Operation); 138 139 void add (MouseButton, Operation, std::string const&, XMLProperty const*); 140 void remove (MouseButton, Operation); 141 bool activate (MouseButton, Operation); 142 143 bool is_bound (KeyboardKey const&, Operation, std::string* path = 0) const; 144 std::string bound_name (KeyboardKey const&, Operation) const; 145 bool is_registered (Operation op, std::string const& action_name) const; 146 147 KeyboardKey get_binding_for_action (Glib::RefPtr<Gtk::Action>, Operation& op); 148 149 bool load (XMLNode const& node); 150 void load_operation (XMLNode const& node); 151 void save (XMLNode& root); 152 void save_as_html (std::ostream&, bool) const; 153 154 /* used for editing bindings */ 155 void get_all_actions (std::vector<std::string>& paths, 156 std::vector<std::string>& labels, 157 std::vector<std::string>& tooltips, 158 std::vector<std::string>& keys, 159 std::vector<Glib::RefPtr<Gtk::Action> >& actions); 160 161 /* all bindings currently in existence, as grouped into Bindings */ reset_bindings()162 static void reset_bindings () { bindings.clear (); } 163 static std::list<Bindings*> bindings; 164 static Bindings* get_bindings (std::string const & name); 165 static void associate_all (); 166 static void save_all_bindings_as_html (std::ostream&); 167 168 static PBD::Signal1<void,Bindings*> BindingsChanged; 169 170 private: 171 std::string _name; 172 KeybindingMap press_bindings; 173 KeybindingMap release_bindings; 174 175 typedef std::map<MouseButton,ActionInfo> MouseButtonBindingMap; 176 MouseButtonBindingMap button_press_bindings; 177 MouseButtonBindingMap button_release_bindings; 178 179 void push_to_gtk (KeyboardKey, Glib::RefPtr<Gtk::Action>); 180 181 KeybindingMap& get_keymap (Operation op); 182 const KeybindingMap& get_keymap (Operation op) const; 183 MouseButtonBindingMap& get_mousemap (Operation op); 184 185 /* GTK has the following position a Gtk::Action: 186 * 187 * accel_path: <Actions>/GroupName/ActionName 188 * name: ActionName 189 * 190 * We want proper namespacing and we're not interested in 191 * the silly <Actions> "extra" namespace. So in Ardour: 192 * 193 * accel_path: <Actions>/GroupName/ActionName 194 * name: GroupName/ActionName 195 * 196 * This (static) method returns the "ardour" name for the action. 197 */ 198 static std::string ardour_action_name (Glib::RefPtr<Gtk::Action>); 199 200 }; 201 202 } // namespace 203 204 std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k); 205 206 #endif /* __libgtkmm2ext_bindings_h__ */ 207