2 Copyright (C) 1999-2007 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
36 void CSelectMsg::saxStartElement( message_info_t *ctx, const xmlChar *name, const xmlChar **attrs ){
37 if ( strcmp( (char *)name, "select" ) == 0 ) {
39 ESelectState = SELECT_MESSAGE;
44 assert( strcmp( (char *)name, "brush" ) == 0 );
45 assert( ESelectState == SELECT_MESSAGE );
46 ESelectState = SELECT_BRUSH;
50 void CSelectMsg::saxEndElement( message_info_t *ctx, const xmlChar *name ){
51 if ( strcmp( (char *)name, "select" ) == 0 ) {
52 ctx->bGeometry = false;
56 void CSelectMsg::saxCharacters( message_info_t *ctx, const xmlChar *ch, int len ){
57 if ( ESelectState == SELECT_MESSAGE ) {
58 message = g_string_sized_new( len + 1 );
59 memcpy( message->str, ch, len );
60 message->str[len] = '\0';
61 Sys_Printf( "%s\n", message->str );
65 assert( ESelectState == SELECT_BRUSH );
66 sscanf( (char *)ch, "%i %i", &entitynum, &brushnum );
70 void CSelectMsg::Highlight(){
72 SelectBrush( entitynum, brushnum );
75 void CPointMsg::saxStartElement( message_info_t *ctx, const xmlChar *name, const xmlChar **attrs ){
76 if ( strcmp( (char *)name, "pointmsg" ) == 0 ) {
78 EPointState = POINT_MESSAGE;
83 assert( strcmp( (char *)name, "point" ) == 0 );
84 assert( EPointState == POINT_MESSAGE );
85 EPointState = POINT_POINT;
89 void CPointMsg::saxEndElement( message_info_t *ctx, const xmlChar *name ){
90 if ( strcmp( (char *)name, "pointmsg" ) == 0 ) {
91 ctx->bGeometry = false;
95 void CPointMsg::saxCharacters( message_info_t *ctx, const xmlChar *ch, int len ){
96 if ( EPointState == POINT_MESSAGE ) {
97 message = g_string_sized_new( len + 1 );
98 memcpy( message->str, ch, len );
99 message->str[len] = '\0';
100 Sys_Printf( "%s\n", message->str );
104 assert( EPointState == POINT_POINT );
105 sscanf( (char *)ch, "%g %g %g", &( pt[0] ), &( pt[1] ), &( pt[2] ) );
109 void CPointMsg::Highlight(){
110 // use the entity API to push a point
111 // the API requires a ref count, we do it manually for the current instance
112 if ( refCount == 0 ) {
114 QERApp_HookGL2DWindow( this );
118 void CPointMsg::DropHighlight(){
119 assert( refCount > 0 );
120 QERApp_UnHookGL2DWindow( this );
121 // do a refCount-- locally (see Highlight)
125 void CPointMsg::Draw2D( VIEWTYPE vt ){
126 int nDim1 = ( vt == YZ ) ? 1 : 0;
127 int nDim2 = ( vt == XY ) ? 1 : 2;
129 qglColor3f( 1.0f,0.0f,0.0f );
130 qglBegin( GL_POINTS );
131 qglVertex2f( pt[nDim1], pt[nDim2] );
133 qglBegin( GL_LINE_LOOP );
134 qglVertex2f( pt[nDim1] - 8, pt[nDim2] - 8 );
135 qglVertex2f( pt[nDim1] + 8, pt[nDim2] - 8 );
136 qglVertex2f( pt[nDim1] + 8, pt[nDim2] + 8 );
137 qglVertex2f( pt[nDim1] - 8, pt[nDim2] + 8 );
141 void CWindingMsg::saxStartElement( message_info_t *ctx, const xmlChar *name, const xmlChar **attrs ){
142 if ( strcmp( (char *)name, "windingmsg" ) == 0 ) {
144 EPointState = WINDING_MESSAGE;
149 assert( strcmp( (char *)name, "winding" ) == 0 );
150 assert( EPointState == WINDING_MESSAGE );
151 EPointState = WINDING_WINDING;
155 void CWindingMsg::saxEndElement( message_info_t *ctx, const xmlChar *name ){
156 if ( strcmp( (char *)name, "windingmsg" ) == 0 ) {
157 ctx->bGeometry = false;
161 void CWindingMsg::saxCharacters( message_info_t *ctx, const xmlChar *ch, int len ){
162 if ( EPointState == WINDING_MESSAGE ) {
163 message = g_string_sized_new( len + 1 );
164 memcpy( message->str, ch, len );
165 message->str[len] = '\0';
166 Sys_Printf( "%s\n", message->str );
173 assert( EPointState == WINDING_WINDING );
177 sscanf( c, "%i ", &numpoints );
179 for ( i = 0; i < numpoints; i++ )
181 c = strchr( ++c, '(' );
182 if ( c ) { // even if we are given the number of points when the cycle begins .. don't trust it too much
183 sscanf( c, "(%g %g %g)", &wt[i][0], &wt[i][1], &wt[i][2] );
193 void CWindingMsg::Highlight(){
194 // use the entity API to push a point
195 // the API requires a ref count, we do it manually for the current instance
196 if ( refCount == 0 ) {
198 QERApp_HookGL2DWindow( this );
202 void CWindingMsg::DropHighlight(){
203 assert( refCount > 0 );
204 QERApp_UnHookGL2DWindow( this );
205 // do a refCount-- locally (see Highlight)
209 void CWindingMsg::Draw2D( VIEWTYPE vt ){
212 int nDim1 = ( vt == YZ ) ? 1 : 0;
213 int nDim2 = ( vt == XY ) ? 1 : 2;
214 qglColor3f( 1.0f,0.f,0.0f );
217 qglBegin( GL_POINTS );
218 for ( i = 0; i < numpoints; i++ )
219 qglVertex2f( wt[i][nDim1], wt[i][nDim2] );
223 qglEnable( GL_BLEND );
224 qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
225 qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
226 qglColor4f( 0.133f,0.4f,1.0f,0.5f );
227 qglBegin( GL_POLYGON );
228 for ( i = 0; i < numpoints; i++ )
229 qglVertex2f( wt[i][nDim1], wt[i][nDim2] );
231 qglDisable( GL_BLEND );
234 // triggered when the user selects an entry in the feedback box
235 static void feedback_selection_changed( GtkTreeSelection* selection, gpointer data ){
236 g_DbgDlg.DropHighlight();
239 GtkTreeIter selected;
240 if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) {
241 GtkTreePath* path = gtk_tree_model_get_path( model, &selected );
242 g_DbgDlg.SetHighlight( gtk_tree_path_get_indices( path )[0] );
243 gtk_tree_path_free( path );
247 void CDbgDlg::DropHighlight(){
248 if ( m_pHighlight ) {
249 m_pHighlight->DropHighlight();
254 void CDbgDlg::SetHighlight( gint row ){
255 ISAXHandler *h = GetElement( row );
262 ISAXHandler *CDbgDlg::GetElement( gint row ) {
263 return static_cast<ISAXHandler *>( g_ptr_array_index( m_pFeedbackElements, row ) );
266 void CDbgDlg::ClearFeedbackArray() {
267 // free all the ISAXHandler*, clean it
268 while ( m_pFeedbackElements->len ) {
269 // some ISAXHandler are static and passed around but should never be deleted
270 ISAXHandler *handler = static_cast< ISAXHandler * >( g_ptr_array_index( m_pFeedbackElements, 0 ) );
271 if ( handler->ShouldDelete() ) {
274 g_ptr_array_remove_index( m_pFeedbackElements, 0 );
278 void CDbgDlg::Init() {
281 ClearFeedbackArray();
283 if ( m_clist != NULL ) {
284 gtk_list_store_clear( m_clist );
288 void CDbgDlg::Push( ISAXHandler *pHandler ) {
290 g_ptr_array_add( m_pFeedbackElements, (void *)pHandler );
292 if ( m_pWidget == NULL ) {
295 // put stuff in the list
296 gtk_list_store_clear( m_clist );
298 for ( i = 0; i < m_pFeedbackElements->len; i++ ) {
300 gtk_list_store_append( m_clist, &iter );
301 gtk_list_store_set( m_clist, &iter, 0, GetElement( i )->getName(), -1 );
307 void CDbgDlg::BuildDialog(){
308 gtk_window_set_title( GTK_WINDOW( m_pWidget ), "Q3Map debug window" );
310 GtkWidget* scr = gtk_scrolled_window_new( NULL, NULL );
311 gtk_widget_show( scr );
312 gtk_container_add( GTK_CONTAINER( m_pWidget ), GTK_WIDGET( scr ) );
313 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scr ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
314 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scr ), GTK_SHADOW_IN );
317 GtkListStore* store = gtk_list_store_new( 1, G_TYPE_STRING );
319 GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
320 gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
323 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
324 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "", renderer, "text", 0, NULL );
325 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
329 GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
330 gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
331 g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( feedback_selection_changed ), NULL );
334 gtk_widget_show( view );
336 gtk_container_add( GTK_CONTAINER( scr ), view );
338 g_object_unref( G_OBJECT( store ) );