2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
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.
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.
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
22 //-----------------------------------------------------------------------------
25 // classes used for describing geometry information from q3map feedback
30 #include "debugging/debugging.h"
33 #include "iselection.h"
35 #include <gtk/gtktreeview.h>
36 #include <gtk/gtktreeselection.h>
37 #include <gtk/gtkliststore.h>
38 #include <gtk/gtkcellrenderertext.h>
39 #include <gtk/gtkwindow.h>
40 #include <gtk/gtkscrolledwindow.h>
44 #include "mainframe.h"
49 void Feedback_draw2D(VIEWTYPE viewType)
51 g_DbgDlg.draw2D(viewType);
54 void CSelectMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs)
56 if(string_equal(reinterpret_cast<const char*>(name), "select"))
59 ESelectState = SELECT_MESSAGE;
64 ASSERT_MESSAGE(string_equal(reinterpret_cast<const char*>(name), "brush"), "FEEDBACK PARSE ERROR");
65 ASSERT_MESSAGE(ESelectState == SELECT_MESSAGE, "FEEDBACK PARSE ERROR");
66 ESelectState = SELECT_BRUSH;
67 globalOutputStream() << message.c_str() << '\n';
71 void CSelectMsg::saxEndElement(message_info_t *ctx, const xmlChar *name)
73 if(string_equal(reinterpret_cast<const char*>(name), "select"))
78 void CSelectMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len)
80 if(ESelectState == SELECT_MESSAGE)
82 message.write(reinterpret_cast<const char*>(ch), len);
86 brush.write(reinterpret_cast<const char*>(ch), len);
90 IGL2DWindow* CSelectMsg::Highlight()
92 GlobalSelectionSystem().setSelectedAll(false);
93 int entitynum, brushnum;
94 if(sscanf(reinterpret_cast<const char*>(brush.c_str()), "%i %i", &entitynum, &brushnum) == 2)
96 SelectBrush (entitynum, brushnum);
101 void CPointMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs)
103 if(string_equal(reinterpret_cast<const char*>(name), "pointmsg"))
106 EPointState = POINT_MESSAGE;
111 ASSERT_MESSAGE(string_equal(reinterpret_cast<const char*>(name), "point"), "FEEDBACK PARSE ERROR");
112 ASSERT_MESSAGE(EPointState == POINT_MESSAGE, "FEEDBACK PARSE ERROR");
113 EPointState = POINT_POINT;
114 globalOutputStream() << message.c_str() << '\n';
118 void CPointMsg::saxEndElement (message_info_t *ctx, const xmlChar *name)
120 if(string_equal(reinterpret_cast<const char*>(name), "pointmsg"))
123 else if(string_equal(reinterpret_cast<const char*>(name), "point"))
125 sscanf(point.c_str(), "%g %g %g", &(pt[0]), &(pt[1]), &(pt[2]));
130 void CPointMsg::saxCharacters (message_info_t *ctx, const xmlChar *ch, int len)
132 if(EPointState == POINT_MESSAGE)
134 message.write(reinterpret_cast<const char*>(ch), len);
138 ASSERT_MESSAGE(EPointState == POINT_POINT, "FEEDBACK PARSE ERROR");
139 point.write(reinterpret_cast<const char*>(ch), len);
143 IGL2DWindow* CPointMsg::Highlight()
148 void CPointMsg::DropHighlight()
152 void CPointMsg::Draw2D( VIEWTYPE vt )
154 int nDim1 = (vt == YZ) ? 1 : 0;
155 int nDim2 = (vt == XY) ? 1 : 2;
157 glColor3f(1.0f,0.0f,0.0f);
159 glVertex2f (pt[nDim1], pt[nDim2]);
161 glBegin (GL_LINE_LOOP);
162 glVertex2f (pt[nDim1]-8, pt[nDim2]-8);
163 glVertex2f (pt[nDim1]+8, pt[nDim2]-8);
164 glVertex2f (pt[nDim1]+8, pt[nDim2]+8);
165 glVertex2f (pt[nDim1]-8, pt[nDim2]+8);
169 void CWindingMsg::saxStartElement(message_info_t *ctx, const xmlChar *name, const xmlChar **attrs)
171 if(string_equal(reinterpret_cast<const char*>(name), "windingmsg"))
174 EPointState = WINDING_MESSAGE;
179 ASSERT_MESSAGE(string_equal(reinterpret_cast<const char*>(name), "winding"), "FEEDBACK PARSE ERROR");
180 ASSERT_MESSAGE(EPointState == WINDING_MESSAGE, "FEEDBACK PARSE ERROR");
181 EPointState = WINDING_WINDING;
182 globalOutputStream() << message.c_str() << '\n';
186 void CWindingMsg::saxEndElement(message_info_t *ctx, const xmlChar *name)
188 if(string_equal(reinterpret_cast<const char*>(name), "windingmsg"))
191 else if(string_equal(reinterpret_cast<const char*>(name), "winding"))
193 const char* c = winding.c_str();
194 sscanf(c, "%i ", &numpoints);
197 for(; i < numpoints; i++)
199 c = strchr(c + 1, '(');
200 if(c) // even if we are given the number of points when the cycle begins .. don't trust it too much
201 sscanf(c, "(%g %g %g)", &wt[i][0], &wt[i][1], &wt[i][2]);
209 void CWindingMsg::saxCharacters(message_info_t *ctx, const xmlChar *ch, int len)
211 if(EPointState == WINDING_MESSAGE)
213 message.write(reinterpret_cast<const char*>(ch), len);
217 ASSERT_MESSAGE(EPointState == WINDING_WINDING, "FEEDBACK PARSE ERROR");
218 winding.write(reinterpret_cast<const char*>(ch), len);
222 IGL2DWindow* CWindingMsg::Highlight()
227 void CWindingMsg::DropHighlight()
231 void CWindingMsg::Draw2D( VIEWTYPE vt )
235 int nDim1 = (vt == YZ) ? 1 : 0;
236 int nDim2 = (vt == XY) ? 1 : 2;
237 glColor3f(1.0f,0.f,0.0f);
241 for(i = 0; i < numpoints; i++)
242 glVertex2f (wt[i][nDim1], wt[i][nDim2]);
247 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
248 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
249 glColor4f(0.133f,0.4f,1.0f,0.5f);
250 glBegin (GL_POLYGON);
251 for(i = 0; i < numpoints; i++)
252 glVertex2f (wt[i][nDim1], wt[i][nDim2]);
254 glDisable (GL_BLEND);
257 // triggered when the user selects an entry in the feedback box
258 static void feedback_selection_changed(GtkTreeSelection* selection, gpointer data)
260 g_DbgDlg.DropHighlight();
263 GtkTreeIter selected;
264 if(gtk_tree_selection_get_selected(selection, &model, &selected))
266 GtkTreePath* path = gtk_tree_model_get_path(model, &selected);
267 g_DbgDlg.SetHighlight(gtk_tree_path_get_indices(path)[0]);
268 gtk_tree_path_free(path);
272 void CDbgDlg::DropHighlight()
274 if(m_pHighlight != 0)
276 m_pHighlight->DropHighlight();
282 void CDbgDlg::SetHighlight(gint row)
284 ISAXHandler *h = GetElement(row);
287 m_pDraw2D = h->Highlight();
292 ISAXHandler *CDbgDlg::GetElement (std::size_t row)
294 return static_cast<ISAXHandler *>(g_ptr_array_index(m_pFeedbackElements, gint(row)));
301 // free all the ISAXHandler*, clean it
302 while (m_pFeedbackElements->len)
304 static_cast<ISAXHandler *>(g_ptr_array_index (m_pFeedbackElements, 0))->Release();
305 g_ptr_array_remove_index (m_pFeedbackElements, 0);
309 gtk_list_store_clear (m_clist);
312 void CDbgDlg::Push (ISAXHandler *pHandler)
315 g_ptr_array_add (m_pFeedbackElements, (void *)pHandler);
322 // put stuff in the list
323 gtk_list_store_clear (m_clist);
324 for(std::size_t i = 0; i < static_cast<std::size_t>(m_pFeedbackElements->len); ++i)
327 gtk_list_store_append(m_clist, &iter);
328 gtk_list_store_set(m_clist, &iter, 0, GetElement(i)->getName(), -1);
334 GtkWindow* CDbgDlg::BuildDialog()
336 GtkWindow* window = create_floating_window("Q3Map debug window", MainFrame_getWindow());
338 GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
339 gtk_widget_show (scr);
340 gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (scr));
341 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
342 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
345 GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING);
347 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
348 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
351 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
352 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
353 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
357 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
358 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
359 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(feedback_selection_changed), NULL);
362 gtk_widget_show(view);
364 gtk_container_add(GTK_CONTAINER (scr), view);
366 g_object_unref(G_OBJECT(store));