1 /*
2  Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3  For a list of contributors, see the accompanying CONTRIBUTORS file.
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 #if !defined(INCLUDED_TEXWINDOW_H)
23 #define INCLUDED_TEXWINDOW_H
24 
25 #include <string>
26 #include <set>
27 #include <glib.h>
28 #include <gtk/gtk.h>
29 #include "generic/callbackfwd.h"
30 #include "signal/signalfwd.h"
31 #include "math/Vector3.h"
32 #include "ishader.h"
33 #include "signal/signal.h"
34 
35 typedef std::set<std::string> TextureGroups;
36 
37 /*
38  ============================================================================
39 
40  TEXTURE LAYOUT
41 
42  TTimo: now based on a rundown through all the shaders
43  NOTE: we expect the Active shaders count doesn't change during a Texture_StartPos .. Texture_NextPos cycle
44  otherwise we may need to rely on a list instead of an array storage
45  ============================================================================
46  */
47 
48 class TextureLayout {
49 	public:
50 		// texture layout functions
51 		// TTimo: now based on shaders
52 		int current_x, current_y, current_row;
TextureLayout()53 		TextureLayout() :
54 			current_x(8), current_y(-8), current_row(0) {
55 		}
56 };
57 
58 class DeferredAdjustment {
59 		gdouble m_value;
60 		guint m_handler;
61 		typedef void (*ValueChangedFunction)(void* data, gdouble value);
62 		ValueChangedFunction m_function;
63 		void* m_data;
64 
deferred_value_changed(gpointer data)65 		static gboolean deferred_value_changed(gpointer data) {
66 			reinterpret_cast<DeferredAdjustment*> (data)->m_function(
67 					reinterpret_cast<DeferredAdjustment*> (data)->m_data,
68 					reinterpret_cast<DeferredAdjustment*> (data)->m_value);
69 			reinterpret_cast<DeferredAdjustment*> (data)->m_handler = 0;
70 			reinterpret_cast<DeferredAdjustment*> (data)->m_value = 0;
71 			return FALSE;
72 		}
73 	public:
DeferredAdjustment(ValueChangedFunction function,void * data)74 		DeferredAdjustment(ValueChangedFunction function, void* data) :
75 			m_value(0), m_handler(0), m_function(function), m_data(data) {
76 		}
flush()77 		void flush() {
78 			if (m_handler != 0) {
79 				g_source_remove(m_handler);
80 				deferred_value_changed(this);
81 			}
82 		}
value_changed(gdouble value)83 		void value_changed(gdouble value) {
84 			m_value = value;
85 			if (m_handler == 0) {
86 				m_handler = g_idle_add(deferred_value_changed, this);
87 			}
88 		}
adjustment_value_changed(GtkAdjustment * adjustment,DeferredAdjustment * self)89 		static void adjustment_value_changed(GtkAdjustment *adjustment, DeferredAdjustment* self) {
90 			self->value_changed(adjustment->value);
91 		}
92 };
93 
94 #include "gtkutil/widget.h"
95 #include "gtkutil/cursor.h"
96 #include "gtkutil/glwidget.h"
97 #include "texturelib.h"
98 #include "math/Vector3.h"
99 #include "preferencesystem.h"
100 #include "iregistry.h"
101 #include "sidebar.h"
102 
103 class TextureBrowser: public RegistryKeyObserver, public PreferenceConstructor, public ui::SidebarComponent
104 {
105 	private:
106 		TextureGroups groups;
107 
108 		int width, height;
109 		int originy;
110 		int m_nTotalHeight;
111 		Signal0 g_activeShadersChangedCallbacks;
112 
113 		std::string shader;
114 		GtkWindow* m_parent;
115 		gtkutil::GLWidget _glWidget;
116 		GtkWidget* _widget;
117 		GtkWidget* m_texture_scroll;
118 		GtkWidget* m_treeViewTree;
119 		GtkWidget* m_scr_win_tree;
120 		GtkWidget* m_scr_win_tags;
121 
122 		bool m_heightChanged;
123 		bool m_originInvalid;
124 
125 		DeferredAdjustment m_scrollAdjustment;
126 		FreezePointer m_freezePointer;
127 
128 		// the increment step we use against the wheel mouse
129 		std::size_t m_mouseWheelScrollIncrement;
130 		std::size_t m_textureScale;
131 		// make the texture increments match the grid changes
132 		bool m_showShaders;
133 		// if true, the texture window will only display in-use shaders
134 		// if false, all the shaders in memory are displayed
135 		bool m_hideUnused;
136 		bool m_hideInvalid;
137 		bool m_rmbSelected;
138 		// If true, textures are resized to an uniform size when displayed in the texture browser.
139 		// If false, textures are displayed in proportion to their pixel size.
140 		bool m_resizeTextures;
141 		// The uniform size (in pixels) that textures are resized to when m_resizeTextures is true.
142 		int m_uniformTextureSize;
143 
144 		std::string currentDirectory;
145 	public:
146 
147 		TextureBrowser();
148 
149 		const std::string& getSelectedShader() const;
150 		void setSelectedShader(const std::string& shader);
151 		void showStartupShaders();
152 		void showDirectory(const std::string& directory);
153 		GtkWidget* getWidget() const;
154 		const std::string getTitle() const;
155 		void activeShadersChanged();
156 		void addActiveShadersChangedCallback(const SignalHandler& handler);
157 		void constructPreferencePage(PreferenceGroup& group);
158 
159 		void keyChanged(const std::string& changedKey, const std::string& newValue);
160 
161 		void registerCommands();
162 
163 		void setOriginY(int originy);
164 		void createWidget();
165 	private:
166 
167 		void focus(const std::string& name);
168 		void selectTextureAt(int mx, int my);
169 		void queueDraw();
170 		bool isTextureShown(const IShader* shader) const;
171 		void updateScroll();
172 		int getFontHeight();
173 		void setStatusText(const std::string& name);
174 
175 		// Return the display width of a texture in the texture browser
176 		int getTextureWidth(const GLTexture* tex);
177 		// Return the display height of a texture in the texture browser
178 		int getTextureHeight(const GLTexture* tex);
179 
180 		void textureScaleImport (int value);
181 
182 		void heightChanged();
183 		void evaluateHeight();
184 		int getTotalHeight();
185 		void clampOriginY();
186 		int getOriginY();
187 		void getNextTexturePosition(TextureLayout& layout, const GLTexture* q, int* x, int* y);
188 		const IShader* getTextureAt(int mx, int my);
189 		void draw();
190 		void onMouseWheel(bool bUp);
191 
192 		static gboolean onMouseMotion(GtkWidget *widget, GdkEventMotion *event,
193 				TextureBrowser* textureBrowser);
194 		static gboolean onButtonRelease(GtkWidget* widget, GdkEventButton* event,
195 				TextureBrowser* textureBrowser);
196 		static gboolean onButtonPress(GtkWidget* widget, GdkEventButton* event,
197 				TextureBrowser* textureBrowser);
198 		static void onToggleResizeTextures(GtkToggleToolButton* button,
199 				TextureBrowser* textureBrowser);
200 
201 		static gboolean onSizeAllocate(GtkWidget* widget, GtkAllocation* allocation,
202 				TextureBrowser* textureBrowser);
203 
204 		static gboolean onExpose(GtkWidget* widget, GdkEventExpose* event,
205 				TextureBrowser* textureBrowser);
206 		static void onVerticalScroll(GtkAdjustment *adjustment, TextureBrowser* textureBrowser);
207 		static gboolean onMouseScroll(GtkWidget* widget, GdkEventScroll* event,
208 				TextureBrowser* textureBrowser);
209 		static void onActivateDirectoryChange(GtkMenuItem* item, TextureBrowser* textureBrowser);
210 
211 		// commands
212 		void refreshShaders();
213 		void showAll(void);
214 
215 		GtkWidget* createMenuBar();
216 		GtkWidget* createToolBar();
217 		GtkMenuItem* constructToolsMenu(GtkMenu* menu);
218 		GtkMenuItem* constructDirectoriesMenu(GtkMenu* menu);
219 		void constructTreeView();
220 };
221 TextureBrowser& GlobalTextureBrowser();
222 
223 void TextureBrowser_Construct();
224 void TextureBrowser_Destroy();
225 
226 typedef Callback1<const char*> StringImportCallback;
227 template<typename FirstArgument, void(*func)(FirstArgument)>
228 class FreeCaller1;
229 
230 #endif
231