]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/windowobservers.cpp
q3map2: fix prt loading for vis computation when using -prtfile
[xonotic/netradiant.git] / radiant / windowobservers.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "windowobservers.h"
23
24 #include <vector>
25 #include <gdk/gdk.h>
26 #include "generic/bitfield.h"
27
28 namespace {
29     ModifierFlags g_modifier_state = c_modifierNone;
30 }
31
32 typedef std::vector<WindowObserver *> WindowObservers;
33
34 inline void WindowObservers_OnModifierDown(WindowObservers &observers, ModifierFlags type)
35 {
36     g_modifier_state = bitfield_enable(g_modifier_state, type);
37     for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) {
38         (*i)->onModifierDown(type);
39     }
40 }
41
42 inline void WindowObservers_OnModifierUp(WindowObservers &observers, ModifierFlags type)
43 {
44     g_modifier_state = bitfield_disable(g_modifier_state, type);
45     for (WindowObservers::iterator i = observers.begin(); i != observers.end(); ++i) {
46         (*i)->onModifierUp(type);
47     }
48 }
49
50 #include <gdk/gdkkeysyms.h>
51
52 gboolean selection_modifier_key_press(ui::Widget widget, GdkEventKey *event, WindowObservers &observers)
53 {
54     switch (event->keyval) {
55         case GDK_KEY_Alt_L:
56         case GDK_KEY_Alt_R:
57             //globalOutputStream() << "Alt PRESSED\n";
58             WindowObservers_OnModifierDown(observers, c_modifierAlt);
59             break;
60         case GDK_KEY_Shift_L:
61         case GDK_KEY_Shift_R:
62             //globalOutputStream() << "Shift PRESSED\n";
63             WindowObservers_OnModifierDown(observers, c_modifierShift);
64             break;
65         case GDK_KEY_Control_L:
66         case GDK_KEY_Control_R:
67             //globalOutputStream() << "Control PRESSED\n";
68             WindowObservers_OnModifierDown(observers, c_modifierControl);
69             break;
70     }
71     return FALSE;
72 }
73
74 gboolean selection_modifier_key_release(ui::Widget widget, GdkEventKey *event, WindowObservers &observers)
75 {
76     switch (event->keyval) {
77         case GDK_KEY_Alt_L:
78         case GDK_KEY_Alt_R:
79             //globalOutputStream() << "Alt RELEASED\n";
80             WindowObservers_OnModifierUp(observers, c_modifierAlt);
81             break;
82         case GDK_KEY_Shift_L:
83         case GDK_KEY_Shift_R:
84             //globalOutputStream() << "Shift RELEASED\n";
85             WindowObservers_OnModifierUp(observers, c_modifierShift);
86             break;
87         case GDK_KEY_Control_L:
88         case GDK_KEY_Control_R:
89             //globalOutputStream() << "Control RELEASED\n";
90             WindowObservers_OnModifierUp(observers, c_modifierControl);
91             break;
92     }
93     return FALSE;
94 }
95
96 void WindowObservers_UpdateModifier(WindowObservers &observers, ModifierFlags modifiers, ModifierFlags modifier)
97 {
98     if (!bitfield_enabled(g_modifier_state, modifier) && bitfield_enabled(modifiers, modifier)) {
99         WindowObservers_OnModifierDown(observers, modifier);
100     }
101     if (bitfield_enabled(g_modifier_state, modifier) && !bitfield_enabled(modifiers, modifier)) {
102         WindowObservers_OnModifierUp(observers, modifier);
103     }
104 }
105
106 void WindowObservers_UpdateModifiers(WindowObservers &observers, ModifierFlags modifiers)
107 {
108     WindowObservers_UpdateModifier(observers, modifiers, c_modifierAlt);
109     WindowObservers_UpdateModifier(observers, modifiers, c_modifierShift);
110     WindowObservers_UpdateModifier(observers, modifiers, c_modifierControl);
111 }
112
113 gboolean modifiers_button_press(ui::Widget widget, GdkEventButton *event, WindowObservers *observers)
114 {
115     if (event->type == GDK_BUTTON_PRESS) {
116         WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state));
117     }
118     return FALSE;
119 }
120
121 gboolean modifiers_button_release(ui::Widget widget, GdkEventButton *event, WindowObservers *observers)
122 {
123     if (event->type == GDK_BUTTON_RELEASE) {
124         WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state));
125     }
126     return FALSE;
127 }
128
129 gboolean modifiers_motion(ui::Widget widget, GdkEventMotion *event, WindowObservers *observers)
130 {
131     WindowObservers_UpdateModifiers(*observers, modifiers_for_state(event->state));
132     return FALSE;
133 }
134
135
136 WindowObservers g_window_observers;
137
138 void GlobalWindowObservers_updateModifiers(ModifierFlags modifiers)
139 {
140     WindowObservers_UpdateModifiers(g_window_observers, modifiers);
141 }
142
143 void GlobalWindowObservers_add(WindowObserver *observer)
144 {
145     g_window_observers.push_back(observer);
146 }
147
148 void GlobalWindowObservers_connectTopLevel(ui::Window window)
149 {
150     window.connect("key_press_event", G_CALLBACK(selection_modifier_key_press), &g_window_observers);
151     window.connect("key_release_event", G_CALLBACK(selection_modifier_key_release), &g_window_observers);
152 }
153
154 void GlobalWindowObservers_connectWidget(ui::Widget widget)
155 {
156     widget.connect("button_press_event", G_CALLBACK(modifiers_button_press), &g_window_observers);
157     widget.connect("button_release_event", G_CALLBACK(modifiers_button_release), &g_window_observers);
158     widget.connect("motion_notify_event", G_CALLBACK(modifiers_motion), &g_window_observers);
159 }
160
161 ModifierFlags modifiers_for_state(unsigned int state)
162 {
163     ModifierFlags modifiers = c_modifierNone;
164     if (state & GDK_SHIFT_MASK) {
165         modifiers |= c_modifierShift;
166     }
167     if (state & GDK_CONTROL_MASK) {
168         modifiers |= c_modifierControl;
169     }
170     if (state & GDK_MOD1_MASK) {
171         modifiers |= c_modifierAlt;
172     }
173     return modifiers;
174 }