3 #include "gtkmm2ext/bindings.h"
4 #include "gtkmm2ext/keyboard.h"
11 using namespace Gtkmm2ext
;
13 uint32_t KeyboardKey::_ignored_state
= 0;
15 KeyboardKey::KeyboardKey (uint32_t state
, uint32_t keycode
)
17 uint32_t ignore
= _ignored_state
;
19 if (gdk_keyval_is_upper (keycode
) && gdk_keyval_is_lower (keycode
)) {
20 /* key is not subject to case, so ignore SHIFT
22 ignore
|= GDK_SHIFT_MASK
;
25 _val
= (state
& ~ignore
);
32 KeyboardKey::name () const
38 if (s
& Keyboard::PrimaryModifier
) {
41 if (s
& Keyboard::SecondaryModifier
) {
47 if (s
& Keyboard::TertiaryModifier
) {
53 if (s
& Keyboard::Level4Modifier
) {
64 str
+= gdk_keyval_name (key());
70 KeyboardKey::make_key (const string
& str
, KeyboardKey
& k
)
74 if (str
.find ("Primary") != string::npos
) {
75 s
|= Keyboard::PrimaryModifier
;
78 if (str
.find ("Secondary") != string::npos
) {
79 s
|= Keyboard::SecondaryModifier
;
82 if (str
.find ("Tertiary") != string::npos
) {
83 s
|= Keyboard::TertiaryModifier
;
86 if (str
.find ("Level4") != string::npos
) {
87 s
|= Keyboard::Level4Modifier
;
90 string::size_type lastmod
= str
.find_last_of ('-');
93 if (lastmod
== string::npos
) {
94 keyval
= gdk_keyval_from_name (str
.c_str());
96 keyval
= gdk_keyval_from_name (str
.substr (lastmod
+1).c_str());
99 if (keyval
== GDK_VoidSymbol
) {
103 k
= KeyboardKey (s
, keyval
);
107 Bindings::Bindings ()
112 Bindings::~Bindings()
117 Bindings::set_action_map (ActionMap
& am
)
120 press_bindings
.clear ();
121 release_bindings
.clear ();
125 Bindings::activate (KeyboardKey kb
, KeyboardKey::Operation op
)
130 case KeyboardKey::Press
:
131 kbm
= &press_bindings
;
133 case KeyboardKey::Release
:
134 kbm
= &release_bindings
;
138 KeybindingMap::iterator k
= kbm
->find (kb
);
140 if (k
== kbm
->end()) {
141 /* no entry for this key in the state map */
147 k
->second
->activate ();
152 Bindings::add (KeyboardKey kb
, KeyboardKey::Operation op
, RefPtr
<Action
> what
)
157 case KeyboardKey::Press
:
158 kbm
= &press_bindings
;
160 case KeyboardKey::Release
:
161 kbm
= &release_bindings
;
165 KeybindingMap::iterator k
= kbm
->find (kb
);
167 if (k
== kbm
->end()) {
168 pair
<KeyboardKey
,RefPtr
<Action
> > newpair (kb
, what
);
169 kbm
->insert (newpair
);
170 cerr
<< "Bindings added " << kb
.key() << " w/ " << kb
.state() << endl
;
177 Bindings::remove (KeyboardKey kb
, KeyboardKey::Operation op
)
182 case KeyboardKey::Press
:
183 kbm
= &press_bindings
;
185 case KeyboardKey::Release
:
186 kbm
= &release_bindings
;
190 KeybindingMap::iterator k
= kbm
->find (kb
);
192 if (k
!= kbm
->end()) {
198 Bindings::save (const string
& path
)
201 XMLNode
* root
= new XMLNode (X_("Bindings"));
202 tree
.set_root (root
);
204 XMLNode
* presses
= new XMLNode (X_("Press"));
205 root
->add_child_nocopy (*presses
);
207 for (KeybindingMap::iterator k
= press_bindings
.begin(); k
!= press_bindings
.end(); ++k
) {
209 child
= new XMLNode (X_("Binding"));
210 child
->add_property (X_("key"), k
->first
.name());
211 child
->add_property (X_("action"), k
->second
->get_name());
212 presses
->add_child_nocopy (*child
);
215 XMLNode
* releases
= new XMLNode (X_("Release"));
216 root
->add_child_nocopy (*releases
);
218 for (KeybindingMap::iterator k
= release_bindings
.begin(); k
!= release_bindings
.end(); ++k
) {
220 child
= new XMLNode (X_("Binding"));
221 child
->add_property (X_("key"), k
->first
.name());
222 child
->add_property (X_("action"), k
->second
->get_name());
223 releases
->add_child_nocopy (*child
);
226 if (!tree
.write (path
)) {
227 ::unlink (path
.c_str());
235 Bindings::load (const string
& path
)
243 if (!tree
.read (path
)) {
247 press_bindings
.clear ();
248 release_bindings
.clear ();
250 XMLNode
& root (*tree
.root());
251 const XMLNodeList
& children (root
.children());
253 for (XMLNodeList::const_iterator i
= children
.begin(); i
!= children
.end(); ++i
) {
255 if ((*i
)->name() == X_("Press") || (*i
)->name() == X_("Release")) {
257 KeyboardKey::Operation op
;
259 if ((*i
)->name() == X_("Press")) {
260 op
= KeyboardKey::Press
;
262 op
= KeyboardKey::Release
;
265 const XMLNodeList
& gchildren ((*i
)->children());
267 for (XMLNodeList::const_iterator p
= gchildren
.begin(); p
!= gchildren
.end(); ++p
) {
272 ap
= (*p
)->property ("action");
273 kp
= (*p
)->property ("key");
279 RefPtr
<Action
> act
= action_map
->find_action (ap
->value());
287 if (!KeyboardKey::make_key (kp
->value(), k
)) {
300 ActionMap::find_action (const string
& name
)
302 _ActionMap::iterator a
= actions
.find (name
);
304 if (a
!= actions
.end()) {
308 return RefPtr
<Action
>();
312 ActionMap::register_action (const char* path
,
313 const char* name
, const char* label
, sigc::slot
<void> sl
)
317 RefPtr
<Action
> act
= Action::create (name
, label
);
319 act
->signal_activate().connect (sl
);
325 actions
.insert (_ActionMap::value_type (fullpath
, act
));
330 ActionMap::register_radio_action (const char* path
, Gtk::RadioAction::Group
& rgroup
,
331 const char* name
, const char* label
,
332 sigc::slot
<void,GtkAction
*> sl
,
337 RefPtr
<Action
> act
= RadioAction::create (rgroup
, name
, label
);
338 RefPtr
<RadioAction
> ract
= RefPtr
<RadioAction
>::cast_dynamic(act
);
339 ract
->property_value() = value
;
341 act
->signal_activate().connect (sigc::bind (sl
, act
->gobj()));
347 actions
.insert (_ActionMap::value_type (fullpath
, act
));
352 ActionMap::register_toggle_action (const char* path
,
353 const char* name
, const char* label
, sigc::slot
<void> sl
)
357 RefPtr
<Action
> act
= ToggleAction::create (name
, label
);
359 act
->signal_activate().connect (sl
);
365 actions
.insert (_ActionMap::value_type (fullpath
, act
));