]> icculus.org git repositories - divverent/netradiant.git/blob - radiant/grid.cpp
fix cloning (don't clone the worldspam)
[divverent/netradiant.git] / radiant / grid.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 "grid.h"
23
24 #include <math.h>
25 #include <vector>
26 #include <algorithm>
27
28 #include "preferencesystem.h"
29
30 #include "gtkutil/widget.h"
31 #include "signal/signal.h"
32 #include "stringio.h"
33
34 #include "gtkmisc.h"
35 #include "commands.h"
36 #include "preferences.h"
37
38
39
40 Signal0 g_gridChange_callbacks;
41
42 void AddGridChangeCallback(const SignalHandler& handler)
43 {
44   g_gridChange_callbacks.connectLast(handler);
45   handler();
46 }
47
48 void GridChangeNotify()
49 {
50   g_gridChange_callbacks();
51 }
52
53 enum GridPower
54 {
55   GRIDPOWER_0125 = -3,
56   GRIDPOWER_025 = -2,
57   GRIDPOWER_05 = -1,
58   GRIDPOWER_1 = 0,
59   GRIDPOWER_2 = 1,
60   GRIDPOWER_4 = 2,
61   GRIDPOWER_8 = 3,
62   GRIDPOWER_16 = 4,
63   GRIDPOWER_32 = 5,
64   GRIDPOWER_64 = 6,
65   GRIDPOWER_128 = 7,
66   GRIDPOWER_256 = 8,
67 };
68
69
70 typedef const char* GridName;
71 // this must match the GridPower enumeration
72 const GridName g_gridnames[] = {
73   "0.125",
74   "0.25",
75   "0.5",
76   "1",
77   "2",
78   "4",
79   "8",
80   "16",
81   "32",
82   "64",
83   "128",
84   "256",
85 };
86
87 inline GridPower GridPower_forGridDefault(int gridDefault)
88 {
89   return static_cast<GridPower>(gridDefault - 3);
90 }
91
92 inline int GridDefault_forGridPower(GridPower gridPower)
93 {
94   return gridPower + 3;
95 }
96
97 int g_grid_default = GridDefault_forGridPower(GRIDPOWER_8);
98
99 int g_grid_power = GridPower_forGridDefault(g_grid_default);
100
101 bool g_grid_snap = true;
102
103 int Grid_getPower()
104 {
105   return g_grid_power;
106 }
107
108 inline float GridSize_forGridPower(int gridPower)
109 {
110   return pow(2.0f, gridPower);
111 }
112
113 float g_gridsize = GridSize_forGridPower(g_grid_power);
114
115 float GetSnapGridSize()
116 {
117   return g_grid_snap ? g_gridsize : 0;
118 }
119
120 float GetGridSize()
121 {
122   return g_gridsize;
123 }
124
125
126 void setGridPower(GridPower power);
127
128 class GridMenuItem
129 {
130   GridPower m_id;
131
132   GridMenuItem(const GridMenuItem& other); // NOT COPYABLE
133   GridMenuItem& operator=(const GridMenuItem& other); // NOT ASSIGNABLE
134 public:
135   ToggleItem m_item;
136
137   GridMenuItem(GridPower id) : m_id(id), m_item(ExportCaller(*this))
138   {
139   }
140   void set()
141   {
142     g_grid_power = m_id;
143     m_item.update();
144     setGridPower(m_id);
145   }
146   typedef MemberCaller<GridMenuItem, &GridMenuItem::set> SetCaller;
147   void active(const BoolImportCallback& importCallback)
148   {
149     importCallback(g_grid_power == m_id);
150   }
151   typedef MemberCaller1<GridMenuItem, const BoolImportCallback&, &GridMenuItem::active> ExportCaller;
152 };
153
154 GridMenuItem g_gridMenu0125(GRIDPOWER_0125);
155 GridMenuItem g_gridMenu025(GRIDPOWER_025);
156 GridMenuItem g_gridMenu05(GRIDPOWER_05);
157 GridMenuItem g_gridMenu1(GRIDPOWER_1);
158 GridMenuItem g_gridMenu2(GRIDPOWER_2);
159 GridMenuItem g_gridMenu4(GRIDPOWER_4);
160 GridMenuItem g_gridMenu8(GRIDPOWER_8);
161 GridMenuItem g_gridMenu16(GRIDPOWER_16);
162 GridMenuItem g_gridMenu32(GRIDPOWER_32);
163 GridMenuItem g_gridMenu64(GRIDPOWER_64);
164 GridMenuItem g_gridMenu128(GRIDPOWER_128);
165 GridMenuItem g_gridMenu256(GRIDPOWER_256);
166
167 void setGridPower(GridPower power)
168 {
169   g_grid_snap = true;
170   g_gridsize = GridSize_forGridPower(power);
171
172   g_gridMenu0125.m_item.update();
173   g_gridMenu025.m_item.update();
174   g_gridMenu05.m_item.update();
175   g_gridMenu1.m_item.update();
176   g_gridMenu2.m_item.update();
177   g_gridMenu4.m_item.update();
178   g_gridMenu8.m_item.update();
179   g_gridMenu16.m_item.update();
180   g_gridMenu32.m_item.update();
181   g_gridMenu64.m_item.update();
182   g_gridMenu128.m_item.update();
183   g_gridMenu256.m_item.update();
184   GridChangeNotify();
185 }
186
187 void GridPrev()
188 {
189   g_grid_snap = true;
190   if(g_grid_power > GRIDPOWER_0125)
191   {
192     setGridPower(static_cast<GridPower>(--g_grid_power));
193   }
194 }
195
196 void GridNext()
197 {
198   g_grid_snap = true;
199   if(g_grid_power < GRIDPOWER_256)
200   {
201     setGridPower(static_cast<GridPower>(++g_grid_power));
202   }
203 }
204
205 void ToggleGridSnap()
206 {
207   g_grid_snap = !g_grid_snap;
208   GridChangeNotify();
209 }
210
211 void Grid_registerCommands()
212 {
213   GlobalCommands_insert("GridDown", FreeCaller<GridPrev>(), Accelerator('['));
214   GlobalCommands_insert("GridUp", FreeCaller<GridNext>(), Accelerator(']'));
215
216   GlobalCommands_insert("ToggleGridSnap", FreeCaller<ToggleGridSnap>());
217
218   GlobalToggles_insert("SetGrid0.125", GridMenuItem::SetCaller(g_gridMenu0125), ToggleItem::AddCallbackCaller(g_gridMenu0125.m_item));
219   GlobalToggles_insert("SetGrid0.25", GridMenuItem::SetCaller(g_gridMenu025), ToggleItem::AddCallbackCaller(g_gridMenu025.m_item));
220   GlobalToggles_insert("SetGrid0.5", GridMenuItem::SetCaller(g_gridMenu05), ToggleItem::AddCallbackCaller(g_gridMenu05.m_item));
221   GlobalToggles_insert("SetGrid1", GridMenuItem::SetCaller(g_gridMenu1), ToggleItem::AddCallbackCaller(g_gridMenu1.m_item), Accelerator('1'));
222   GlobalToggles_insert("SetGrid2", GridMenuItem::SetCaller(g_gridMenu2), ToggleItem::AddCallbackCaller(g_gridMenu2.m_item), Accelerator('2'));
223   GlobalToggles_insert("SetGrid4", GridMenuItem::SetCaller(g_gridMenu4), ToggleItem::AddCallbackCaller(g_gridMenu4.m_item), Accelerator('3'));
224   GlobalToggles_insert("SetGrid8", GridMenuItem::SetCaller(g_gridMenu8), ToggleItem::AddCallbackCaller(g_gridMenu8.m_item), Accelerator('4'));
225   GlobalToggles_insert("SetGrid16", GridMenuItem::SetCaller(g_gridMenu16), ToggleItem::AddCallbackCaller(g_gridMenu16.m_item), Accelerator('5'));
226   GlobalToggles_insert("SetGrid32", GridMenuItem::SetCaller(g_gridMenu32), ToggleItem::AddCallbackCaller(g_gridMenu32.m_item), Accelerator('6'));
227   GlobalToggles_insert("SetGrid64", GridMenuItem::SetCaller(g_gridMenu64), ToggleItem::AddCallbackCaller(g_gridMenu64.m_item), Accelerator('7'));
228   GlobalToggles_insert("SetGrid128", GridMenuItem::SetCaller(g_gridMenu128), ToggleItem::AddCallbackCaller(g_gridMenu128.m_item), Accelerator('8'));
229   GlobalToggles_insert("SetGrid256", GridMenuItem::SetCaller(g_gridMenu256), ToggleItem::AddCallbackCaller(g_gridMenu256.m_item), Accelerator('9'));
230 }
231
232
233 void Grid_constructMenu(GtkMenu* menu)
234 {
235   create_check_menu_item_with_mnemonic(menu, "Grid0.125", "SetGrid0.125");
236   create_check_menu_item_with_mnemonic(menu, "Grid0.25", "SetGrid0.25");
237   create_check_menu_item_with_mnemonic(menu, "Grid0.5", "SetGrid0.5");
238   create_check_menu_item_with_mnemonic(menu, "Grid1", "SetGrid1");
239   create_check_menu_item_with_mnemonic(menu, "Grid2", "SetGrid2");
240   create_check_menu_item_with_mnemonic(menu, "Grid4", "SetGrid4");
241   create_check_menu_item_with_mnemonic(menu, "Grid8", "SetGrid8");
242   create_check_menu_item_with_mnemonic(menu, "Grid16", "SetGrid16");
243   create_check_menu_item_with_mnemonic(menu, "Grid32", "SetGrid32");
244   create_check_menu_item_with_mnemonic(menu, "Grid64", "SetGrid64");
245   create_check_menu_item_with_mnemonic(menu, "Grid128", "SetGrid128");
246   create_check_menu_item_with_mnemonic(menu, "Grid256", "SetGrid256");
247 }
248
249 void Grid_registerShortcuts()
250 {
251   command_connect_accelerator("ToggleGrid");
252   command_connect_accelerator("GridDown");
253   command_connect_accelerator("GridUp");
254   command_connect_accelerator("ToggleGridSnap");
255 }
256
257 void Grid_constructPreferences(PreferencesPage& page)
258 {
259   page.appendCombo(
260     "Default grid spacing",
261     g_grid_default,
262     ARRAY_RANGE(g_gridnames)
263   );
264 }
265 void Grid_constructPage(PreferenceGroup& group)
266 {
267   PreferencesPage page(group.createPage("Grid", "Grid Settings"));
268   Grid_constructPreferences(page);
269 }
270 void Grid_registerPreferencesPage()
271 {
272   PreferencesDialog_addSettingsPage(FreeCaller1<PreferenceGroup&, Grid_constructPage>());
273 }
274
275 void Grid_construct()
276 {
277   Grid_registerPreferencesPage();
278
279   g_grid_default = GridDefault_forGridPower(GRIDPOWER_8);
280
281   GlobalPreferenceSystem().registerPreference("GridDefault", IntImportStringCaller(g_grid_default), IntExportStringCaller(g_grid_default));
282
283   g_grid_power = GridPower_forGridDefault(g_grid_default);
284   g_gridsize = GridSize_forGridPower(g_grid_power);
285 }
286
287 void Grid_destroy()
288 {
289 }