1 #include "igrid.h"
2 
3 #include <map>
4 #include "iradiant.h"
5 #include "ieventmanager.h"
6 #include "iregistry.h"
7 #include "preferencesystem.h"
8 #include "signal/signal.h"
9 #include "radiant_i18n.h"
10 
11 #include <iostream>
12 
13 #include "GridItem.h"
14 
15 namespace {
16 const std::string RKEY_DEFAULT_GRID_SIZE = "user/ui/grid/defaultGridPower";
17 const std::string RKEY_GRID_LOOK_MAJOR = "user/ui/grid/majorGridLook";
18 const std::string RKEY_GRID_LOOK_MINOR = "user/ui/grid/minorGridLook";
19 }
20 
21 class GridManager: public IGridManager, public RegistryKeyObserver, public PreferenceConstructor
22 {
23 	public:
24 		// Radiant Module stuff
25 		typedef IGridManager Type;
26 		STRING_CONSTANT(Name, "*");
27 
28 		// Return the static instance
getTable()29 		IGridManager* getTable ()
30 		{
31 			return this;
32 		}
33 
34 	private:
35 		typedef std::map<const std::string, GridItem> GridItemMap;
36 
37 		GridItemMap _gridItems;
38 
39 		// The currently active grid size
40 		GridSize _activeGridSize;
41 
42 		Signal0 _gridChangeCallbacks;
43 
44 	public:
GridManager()45 		GridManager () :
46 			_activeGridSize(GRID_8)
47 		{
48 			populateGridItems();
49 			registerCommands();
50 
51 			// Connect self to the according registry keys
52 			GlobalRegistry().addKeyObserver(this, RKEY_DEFAULT_GRID_SIZE);
53 
54 			// greebo: Register this class in the preference system so that the constructPreferencePage() gets called.
55 			GlobalPreferenceSystem().addConstructor(this);
56 
57 			// Load the default value from the registry
58 			keyChanged("", "");
59 		}
60 
keyChanged(const std::string & changedKey,const std::string & newValue)61 		void keyChanged (const std::string& changedKey, const std::string& newValue)
62 		{
63 			// Get the registry value
64 			int registryValue = GlobalRegistry().getInt(RKEY_DEFAULT_GRID_SIZE);
65 
66 			// Constrain the values to the allowed ones
67 			if (registryValue < GRID_0125) {
68 				registryValue = static_cast<int> (GRID_0125);
69 			}
70 
71 			if (registryValue > GRID_256) {
72 				registryValue = static_cast<int> (GRID_256);
73 			}
74 
75 			_activeGridSize = static_cast<GridSize> (registryValue);
76 
77 			// Notify the world about the grid change
78 			gridChangeNotify();
79 		}
80 
populateGridItems()81 		void populateGridItems ()
82 		{
83 			// Populate the GridItem map
84 			_gridItems["0.125"] = GridItem(GRID_0125, this);
85 			_gridItems["0.25"] = GridItem(GRID_025, this);
86 			_gridItems["0.5"] = GridItem(GRID_05, this);
87 			_gridItems["1"] = GridItem(GRID_1, this);
88 			_gridItems["2"] = GridItem(GRID_2, this);
89 			_gridItems["4"] = GridItem(GRID_4, this);
90 			_gridItems["8"] = GridItem(GRID_8, this);
91 			_gridItems["16"] = GridItem(GRID_16, this);
92 			_gridItems["32"] = GridItem(GRID_32, this);
93 			_gridItems["64"] = GridItem(GRID_64, this);
94 			_gridItems["128"] = GridItem(GRID_128, this);
95 			_gridItems["256"] = GridItem(GRID_256, this);
96 		}
97 
registerCommands()98 		void registerCommands ()
99 		{
100 			for (GridItemMap::iterator i = _gridItems.begin(); i != _gridItems.end(); ++i) {
101 				std::string toggleName = "SetGrid";
102 				toggleName += i->first; // Makes "SetGrid" to "SetGrid64", for example
103 				GridItem& gridItem = i->second;
104 
105 				GlobalEventManager().addToggle(toggleName, GridItem::ActivateCaller(gridItem));
106 			}
107 
108 			GlobalEventManager().addCommand("GridDown", MemberCaller<GridManager, &GridManager::gridDown> (*this));
109 			GlobalEventManager().addCommand("GridUp", MemberCaller<GridManager, &GridManager::gridUp> (*this));
110 		}
111 
getGridList()112 		ComboBoxValueList getGridList ()
113 		{
114 			ComboBoxValueList returnValue;
115 
116 			for (GridItemMap::iterator i = _gridItems.begin(); i != _gridItems.end(); ++i) {
117 				returnValue.push_back(i->first);
118 			}
119 
120 			return returnValue;
121 		}
122 
constructPreferencePage(PreferenceGroup & group)123 		void constructPreferencePage (PreferenceGroup& group)
124 		{
125 			PreferencesPage* page(group.createPage(_("Grid"), _("Default Grid Settings")));
126 			page->appendCombo("Default Grid Size", RKEY_DEFAULT_GRID_SIZE, getGridList());
127 
128 			ComboBoxValueList looks;
129 
130 			looks.push_back(_("Lines"));
131 			looks.push_back(_("Dotted Lines"));
132 			looks.push_back(_("More Dotted Lines"));
133 			looks.push_back(_("Crosses"));
134 			looks.push_back(_("Dots"));
135 			looks.push_back(_("Big Dots"));
136 			looks.push_back(_("Squares"));
137 
138 			page->appendCombo(_("Major Grid Style"), RKEY_GRID_LOOK_MAJOR, looks);
139 			page->appendCombo(_("Minor Grid Style"), RKEY_GRID_LOOK_MINOR, looks);
140 		}
141 
addGridChangeCallback(const SignalHandler & handler)142 		void addGridChangeCallback (const SignalHandler& handler)
143 		{
144 			_gridChangeCallbacks.connectLast(handler);
145 			handler();
146 		}
147 
gridChangeNotify()148 		void gridChangeNotify ()
149 		{
150 			_gridChangeCallbacks();
151 		}
152 
gridDown()153 		void gridDown ()
154 		{
155 			if (_activeGridSize > GRID_0125) {
156 				int _activeGridIndex = static_cast<int> (_activeGridSize);
157 				_activeGridIndex--;
158 				setGridSize(static_cast<GridSize> (_activeGridIndex));
159 			}
160 		}
161 
gridUp()162 		void gridUp ()
163 		{
164 			if (_activeGridSize < GRID_256) {
165 				int _activeGridIndex = static_cast<int> (_activeGridSize);
166 				_activeGridIndex++;
167 				setGridSize(static_cast<GridSize> (_activeGridIndex));
168 			}
169 		}
170 
setGridSize(GridSize gridSize)171 		void setGridSize (GridSize gridSize)
172 		{
173 			_activeGridSize = gridSize;
174 
175 			gridChanged();
176 		}
177 
getGridSize() const178 		float getGridSize () const
179 		{
180 			return pow(2.0f, static_cast<int> (_activeGridSize));
181 		}
182 
getGridPower() const183 		int getGridPower () const
184 		{
185 			return static_cast<int> (_activeGridSize);
186 		}
187 
gridChanged()188 		void gridChanged ()
189 		{
190 			for (GridItemMap::iterator i = _gridItems.begin(); i != _gridItems.end(); ++i) {
191 				std::string toggleName = "SetGrid";
192 				toggleName += i->first; // Makes "SetGrid" to "SetGrid64", for example
193 				GridItem& gridItem = i->second;
194 
195 				GlobalEventManager().setToggled(toggleName, _activeGridSize == gridItem.getGridSize());
196 			}
197 
198 			gridChangeNotify();
199 		}
200 
getLookFromNumber(int i)201 		static GridLook getLookFromNumber (int i)
202 		{
203 			if (i >= GRIDLOOK_LINES && i <= GRIDLOOK_SQUARES) {
204 				return static_cast<GridLook> (i);
205 			}
206 
207 			return GRIDLOOK_LINES;
208 		}
209 
getMajorLook() const210 		GridLook getMajorLook () const
211 		{
212 			return getLookFromNumber(GlobalRegistry().getInt(RKEY_GRID_LOOK_MAJOR));
213 		}
214 
getMinorLook() const215 		GridLook getMinorLook () const
216 		{
217 			return getLookFromNumber(GlobalRegistry().getInt(RKEY_GRID_LOOK_MINOR));
218 		}
219 }; // class GridManager
220 
221 /* GridManager dependencies class.
222  */
223 class GridManagerDependencies: public GlobalRadiantModuleRef,
224 		public GlobalRegistryModuleRef,
225 		public GlobalEventManagerModuleRef,
226 		public GlobalPreferenceSystemModuleRef
227 {
228 };
229 
230 /* Required code to register the module with the ModuleServer.
231  */
232 
233 #include "modulesystem/singletonmodule.h"
234 
235 typedef SingletonModule<GridManager, GridManagerDependencies> GridManagerModule;
236 
237 typedef Static<GridManagerModule> StaticGridManagerSystemModule;
238 StaticRegisterModule staticRegisterGridManagerSystem(StaticGridManagerSystemModule::instance());
239