diff --git a/libs/eclasslib.h b/libs/eclasslib.h index 79436d53..4b1612b1 100644 --- a/libs/eclasslib.h +++ b/libs/eclasslib.h @@ -125,6 +125,7 @@ Shader* m_state_blend; CopiedString m_comments; char flagnames[MAX_FLAGS][32]; +const EntityClassAttribute* flagAttributes[MAX_FLAGS]; CopiedString m_modelpath; CopiedString m_skin; @@ -261,6 +262,7 @@ inline EntityClass* Eclass_Alloc(){ e->m_miscmodel_key = "model"; e->has_angles = false; memset( e->flagnames, 0, MAX_FLAGS * 32 ); + memset( e->flagAttributes, 0, MAX_FLAGS * sizeof( EntityClassAttribute* ) ); e->maxs = Vector3( -1,-1,-1 ); e->mins = Vector3( 1, 1, 1 ); diff --git a/radiant/eclass_xml.cpp b/radiant/eclass_xml.cpp index fdf81272..94df80af 100644 --- a/radiant/eclass_xml.cpp +++ b/radiant/eclass_xml.cpp @@ -193,6 +193,8 @@ class AttributeImporter : public TreeXMLImporter { StringOutputStream& m_comment; +EntityClassAttribute* m_attribute; + public: AttributeImporter( StringOutputStream& comment, EntityClass* entityClass, const XMLElement& element ) : m_comment( comment ){ const char* type = element.name(); @@ -203,11 +205,14 @@ AttributeImporter( StringOutputStream& comment, EntityClass* entityClass, const ASSERT_MESSAGE( !string_empty( key ), "key attribute not specified" ); ASSERT_MESSAGE( !string_empty( name ), "name attribute not specified" ); + m_attribute = &EntityClass_insertAttribute( *entityClass, key, EntityClassAttribute( type, name, value ) ).second; + if ( string_equal( type, "flag" ) ) { std::size_t bit = atoi( element.attribute( "bit" ) ); ASSERT_MESSAGE( bit < MAX_FLAGS, "invalid flag bit" ); ASSERT_MESSAGE( string_empty( entityClass->flagnames[bit] ), "non-unique flag bit" ); strcpy( entityClass->flagnames[bit], key ); + entityClass->flagAttributes[bit] = m_attribute; } else if( entityClass->fixedsize && string_equal( type, "model" ) ){ entityClass->miscmodel_is = true; @@ -219,8 +224,6 @@ AttributeImporter( StringOutputStream& comment, EntityClass* entityClass, const m_comment << key; m_comment << " : "; - - EntityClass_insertAttribute( *entityClass, key, EntityClassAttribute( type, name, value ) ); } ~AttributeImporter(){ } @@ -232,6 +235,7 @@ void popElement( const char* elementName ){ ERROR_MESSAGE( PARSE_ERROR( elementName, "attribute" ) ); } std::size_t write( const char* data, std::size_t length ){ + m_attribute->m_description = StringRange( data, data + length ); return m_comment.write( data, length ); } }; diff --git a/radiant/entityinspector.cpp b/radiant/entityinspector.cpp index 6c62b582..78befaa2 100644 --- a/radiant/entityinspector.cpp +++ b/radiant/entityinspector.cpp @@ -993,6 +993,16 @@ void SetComment( EntityClass* eclass ){ } } +void EntityAttribute_setTooltip( GtkWidget* widget, const char* name, const char* description ){ + StringOutputStream stream( 256 ); + if( string_not_empty( name ) ) + stream << " " << name << " "; + if( string_not_empty( description ) ) + stream << "\n" << description; + if( !stream.empty() ) + gtk_widget_set_tooltip_markup( widget, stream.c_str() ); +} + void SurfaceFlags_setEntityClass( EntityClass* eclass ){ if ( eclass == g_current_flags ) { return; @@ -1043,6 +1053,10 @@ void SurfaceFlags_setEntityClass( EntityClass* eclass ){ gtk_widget_unref( widget ); gtk_label_set_text( GTK_LABEL( GTK_BIN( widget )->child ), str.c_str() ); + + if( const EntityClassAttribute* attribute = eclass->flagAttributes[i] ){ + EntityAttribute_setTooltip( widget, attribute->m_name.c_str(), attribute->m_description.c_str() ); + } } } } @@ -1068,8 +1082,10 @@ void EntityClassList_selectEntityClass( EntityClass* eclass ){ } } -void EntityInspector_appendAttribute( const char* name, EntityAttribute& attribute ){ - GtkTable* row = DialogRow_new( name, attribute.getWidget() ); +void EntityInspector_appendAttribute( const EntityClassAttributePair& attributePair, EntityAttribute& attribute ){ + const char* keyname = attributePair.first.c_str(); //EntityClassAttributePair_getName( attributePair ); + GtkTable* row = DialogRow_new( keyname, attribute.getWidget() ); + EntityAttribute_setTooltip( GTK_WIDGET( row ), attributePair.second.m_name.c_str(), attributePair.second.m_description.c_str() ); DialogVBox_packRow( g_attributeBox, GTK_WIDGET( row ) ); } @@ -1139,7 +1155,7 @@ void EntityInspector_setEntityClass( EntityClass *eclass ){ EntityAttribute* attribute = GlobalEntityAttributeFactory::instance().create( ( *i ).second.m_type.c_str(), ( *i ).first.c_str() ); if ( attribute != 0 ) { g_entityAttributes.push_back( attribute ); - EntityInspector_appendAttribute( EntityClassAttributePair_getName( *i ), *g_entityAttributes.back() ); + EntityInspector_appendAttribute( *i, *g_entityAttributes.back() ); } } }