]> git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge commit '54a2bda443aace9c00a1615af10cc1dc8b1f0cd1' into master-merge
authorThomas Debesse <dev@illwieckz.net>
Tue, 21 Jun 2022 04:29:46 +0000 (06:29 +0200)
committerThomas Debesse <dev@illwieckz.net>
Tue, 21 Jun 2022 04:29:46 +0000 (06:29 +0200)
16 files changed:
libs/gtkutil/accelerator.cpp
libs/picomodel/pm_mdc.c
libs/stringio.h
plugins/md3model/md5.cpp
radiant/camwindow.cpp
radiant/eclass_doom3.cpp
radiant/entity.cpp
radiant/entity.h
radiant/entityinspector.cpp
radiant/mainframe.cpp
radiant/preferences.cpp
radiant/preferences.h
radiant/texwindow.cpp
radiant/xywindow.cpp
tools/quake3/common/scriplib.c
tools/quake3/q3map2/portals.c

index 00380d452f8eb6c66fcac93a0439693c0b2f0cee..a17931decaff3649809e4c73fa656b1f946aa142 100644 (file)
@@ -329,14 +329,14 @@ AcceleratorMap g_keydown_accelerators;
 AcceleratorMap g_keyup_accelerators;
 
 bool Keys_press( PressedKeys::Keys& keys, guint keyval ){
-       if ( keys.insert( keyval ).second ) {
+       if ( keys.insert( gdk_keyval_to_upper( keyval ) ).second ) {
                return AcceleratorMap_activate( g_keydown_accelerators, accelerator_for_event_key( keyval, 0 ) );
        }
        return g_keydown_accelerators.find( accelerator_for_event_key( keyval, 0 ) ) != g_keydown_accelerators.end();
 }
 
 bool Keys_release( PressedKeys::Keys& keys, guint keyval ){
-       if ( keys.erase( keyval ) != 0 ) {
+       if ( keys.erase( gdk_keyval_to_upper( keyval ) ) != 0 ) {
                return AcceleratorMap_activate( g_keyup_accelerators, accelerator_for_event_key( keyval, 0 ) );
        }
        return g_keyup_accelerators.find( accelerator_for_event_key( keyval, 0 ) ) != g_keyup_accelerators.end();
index ec40d5a9c842ae2fccb766505bf3dd52cee4d3ab..816adebb6ff1c0d35ae4c9ee5f600d6302b06156 100644 (file)
@@ -45,7 +45,7 @@ const float MDC_MAX_OFS         = 127.0f;
 const float MDC_DIST_SCALE      = 0.05f;
 
 /* mdc decoding normal table */
-double mdcNormals[ 256 ][ 3 ] =
+const double mdcNormals[ 256 ][ 3 ] =
 {
        { 1.000000, 0.000000, 0.000000 },
        { 0.980785, 0.195090, 0.000000 },
index 227927291ebbe8b8ebf37e1f6cc93631da26dbf1..544b433674a73ca292a37168150e08c886fde2af 100644 (file)
@@ -220,7 +220,7 @@ inline bool string_parse_size( const char* string, std::size_t& i ){
 }
 
 
-#define RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) return false; } while (0)
+#define RETURN_FALSE_IF_FAIL( expression ) do{ if ( !expression ) {return false; } }while( 0 )
 
 inline void Tokeniser_unexpectedError( Tokeniser& tokeniser, const char* token, const char* expected ){
        globalErrorStream() << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n";
index e1c5de56d23f0ea0e4ec149a6c62115d9a0992b8..8fea68d7844ba904a28318b9a4dfa3ac7547f44d 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "model.h"
 
-#define MD5_RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) { globalErrorStream() << "md5 parse failed: " #expression "\n"; return false; } } while (0)
+#define MD5_RETURN_FALSE_IF_FAIL( expression ) do{ if ( !( expression ) ) { globalErrorStream() << "md5 parse failed: " # expression "\n"; return false; } }while( 0 )
 
 bool MD5_parseToken( Tokeniser& tokeniser, const char* string ){
        const char* token = tokeniser.getToken();
index 9d89bbfb0be952eddd95670299d5f06f76a705df..4eb6fb06e5f6c07c2cabeb30b9c01544a7b29916 100644 (file)
@@ -844,6 +844,7 @@ void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){
 
 gboolean selection_button_press( ui::Widget widget, GdkEventButton* event, WindowObserver* observer ){
        if ( event->type == GDK_BUTTON_PRESS ) {
+               gtk_widget_grab_focus( widget );
                observer->onMouseDown( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) );
        }
        return FALSE;
@@ -886,6 +887,11 @@ gboolean selection_motion_freemove( ui::Widget widget, GdkEventMotion *event, Wi
 }
 
 gboolean wheelmove_scroll( ui::Widget widget, GdkEventScroll* event, CamWnd* camwnd ){
+       //gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget );
+       gtk_widget_grab_focus( camwnd->m_gl_widget );
+       if( !gtk_window_is_active( camwnd->m_parent ) )
+               gtk_window_present( camwnd->m_parent );
+
        if ( event->direction == GDK_SCROLL_UP ) {
                Camera_Freemove_updateAxes( camwnd->getCamera() );
                if( camwnd->m_bFreeMove || !g_camwindow_globals.m_bZoomInToPointer ){
index 4c7525ea4fdb9219bd60c0b958946954c5b2db5a..b6a5344037ef8b6038e51bc8ce2dcf2f30947f7c 100644 (file)
@@ -84,7 +84,7 @@ inline void printParseError( const char* message ){
        globalErrorStream() << message;
 }
 
-#define PARSE_RETURN_FALSE_IF_FAIL(expression) do { if (!( expression)) { printParseError(FILE_LINE "\nparse failed: " #expression "\n"); return false; } } while (0)
+#define PARSE_RETURN_FALSE_IF_FAIL( expression ) do{ if ( !( expression ) ) { printParseError( FILE_LINE "\nparse failed: " # expression "\n" ); return false; } }while( 0 )
 
 bool EntityClassDoom3_parseToken( Tokeniser& tokeniser ){
        const char* token = tokeniser.getToken();
index 728307a66f4f3f1fdc2ab83c98e57b56fde5599f..3a7eddb258218c287da5bc146daeca682c1f6a0c 100644 (file)
@@ -316,6 +316,19 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){
 
        bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;
 
+       //is important to have retexturing here; if doing in the end, undo doesn't succeed;
+       if ( string_compare_nocase_n( name, "trigger_", 8 ) == 0 && brushesSelected ){
+               const char* shader = g_pGameDescription->getKeyValue( "shader_trigger" );
+               if ( shader && *shader ){
+                       Scene_PatchSetShader_Selected( GlobalSceneGraph(), shader );
+                       Scene_BrushSetShader_Selected( GlobalSceneGraph(), shader );
+               }
+               else{
+                       Scene_PatchSetShader_Selected( GlobalSceneGraph(), "textures/common/trigger" );
+                       Scene_BrushSetShader_Selected( GlobalSceneGraph(), "textures/common/trigger" );
+               }
+       }
+
        if ( !( entityClass->fixedsize || isModel ) && !brushesSelected ) {
                globalErrorStream() << "failed to create a group entity - no brushes are selected\n";
                return;
@@ -402,18 +415,6 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){
                        Node_getEntity( node )->setKeyValue( "model", model );
                }
        }
-
-       if ( string_compare_nocase_n( name, "trigger_", 8 ) == 0 && brushesSelected ){
-               const char* shader = g_pGameDescription->getKeyValue( "shader_trigger" );
-               if ( shader && *shader ){
-                       Scene_PatchSetShader_Selected( GlobalSceneGraph(), shader );
-                       Scene_BrushSetShader_Selected( GlobalSceneGraph(), shader );
-               }
-               else{
-                       Scene_PatchSetShader_Selected( GlobalSceneGraph(), "textures/common/trigger" );
-                       Scene_BrushSetShader_Selected( GlobalSceneGraph(), "textures/common/trigger" );
-               }
-       }
 }
 
 #if 0
index fca38f92cd4c598852325ceccc19a725b4f9912f..d655774cde72d9207c9a34ecfd01fcf0e5cbf8a9 100644 (file)
@@ -33,6 +33,7 @@ void Scene_EntitySetClassname_Selected( const char* classname );
 
 
 const char* misc_model_dialog( ui::Widget parent );
+void Entity_setColour();
 
 void Entity_constructMenu( ui::Menu menu );
 
index 349d5d09b5fd34d47f3bf14f3a807121bbd6cd24..564d7173e3cfb328a9dbf4554fa5849567e9d1e0 100644 (file)
@@ -209,6 +209,52 @@ ShaderAttribute( const char* key ) : StringAttribute( key ){
 };
 
 
+class ColorAttribute : public EntityAttribute
+{
+CopiedString m_key;
+BrowsedPathEntry m_entry;
+NonModalEntry m_nonModal;
+public:
+ColorAttribute( const char* key ) :
+       m_key( key ),
+       m_entry( BrowseCaller( *this ) ),
+       m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){
+       m_nonModal.connect( m_entry.m_entry.m_entry );
+}
+void release(){
+       delete this;
+}
+ui::Widget getWidget() const {
+       return ui::Widget( m_entry.m_entry.m_frame );
+}
+void apply(){
+       StringOutputStream value( 64 );
+       value << gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) );
+       Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() );
+}
+typedef MemberCaller<ColorAttribute, void(), &ColorAttribute::apply> ApplyCaller;
+void update(){
+       StringOutputStream value( 64 );
+       value << SelectedEntity_getValueForKey( m_key.c_str() );
+       gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), value.c_str() );
+}
+typedef MemberCaller<ColorAttribute, void(), &ColorAttribute::update> UpdateCaller;
+void browse( const BrowsedPathEntry::SetPathCallback& setPath ){
+       //const char *filename = misc_model_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ) );
+
+       /* hijack BrowsedPathEntry to call colour chooser */
+       Entity_setColour();
+
+//     if ( filename != 0 ) {
+//             setPath( filename );
+//             apply();
+//     }
+       update();
+}
+typedef MemberCaller<ColorAttribute, void(const BrowsedPathEntry::SetPathCallback&), &ColorAttribute::browse> BrowseCaller;
+};
+
+
 class ModelAttribute : public EntityAttribute
 {
 CopiedString m_key;
@@ -833,6 +879,36 @@ void SetComment( EntityClass* eclass ){
        g_current_comment = eclass;
 
        g_entityClassComment.text(eclass->comments());
+
+       GtkTextBuffer* buffer = gtk_text_view_get_buffer( g_entityClassComment );
+       //gtk_text_buffer_set_text( buffer, eclass->comments(), -1 );
+       const char* comment = eclass->comments(), *c;
+       int offset = 0, pattern_start = -1, spaces = 0;
+
+       gtk_text_buffer_set_text( buffer, comment, -1 );
+
+       // Catch patterns like "\nstuff :" used to describe keys and spawnflags, and make them bold for readability.
+
+       for( c = comment; *c; ++c, ++offset ) {
+               if( *c == '\n' ) {
+                       pattern_start = offset;
+                       spaces = 0;
+               }
+               else if( pattern_start >= 0 && ( *c < 'a' || *c > 'z' ) && ( *c < 'A' || *c > 'Z' ) && ( *c < '0' || *c > '9' ) && ( *c != '_' ) ) {
+                       if( *c == ':' && spaces <= 1 ) {
+                               GtkTextIter iter_start, iter_end;
+
+                               gtk_text_buffer_get_iter_at_offset( buffer, &iter_start, pattern_start );
+                               gtk_text_buffer_get_iter_at_offset( buffer, &iter_end, offset );
+                               gtk_text_buffer_apply_tag_by_name( buffer, "bold", &iter_start, &iter_end );
+                       }
+
+                       if( *c == ' ' )
+                               ++spaces;
+                       else
+                               pattern_start = -1;
+               }
+       }
 }
 
 void SurfaceFlags_setEntityClass( EntityClass* eclass ){
@@ -933,7 +1009,7 @@ Creators m_creators;
 public:
 EntityAttributeFactory(){
        m_creators.insert( Creators::value_type( "string", &StatelessAttributeCreator<StringAttribute>::create ) );
-       m_creators.insert( Creators::value_type( "color", &StatelessAttributeCreator<StringAttribute>::create ) );
+       m_creators.insert( Creators::value_type( "color", &StatelessAttributeCreator<ColorAttribute>::create ) );
        m_creators.insert( Creators::value_type( "integer", &StatelessAttributeCreator<StringAttribute>::create ) );
        m_creators.insert( Creators::value_type( "real", &StatelessAttributeCreator<StringAttribute>::create ) );
        m_creators.insert( Creators::value_type( "shader", &StatelessAttributeCreator<ShaderAttribute>::create ) );
@@ -1398,6 +1474,10 @@ ui::Widget EntityInspector_constructWindow( ui::Window toplevel ){
                                        text.show();
                                        scr.add(text);
                                        g_entityClassComment = text;
+                                       {
+                                               GtkTextBuffer *buffer = gtk_text_view_get_buffer( text );
+                                               gtk_text_buffer_create_tag( buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL );
+                                       }
                                }
                        }
                }
index be017b027119e952e32cce299e7c27f03a25526a..9148ab0a3b80556119b64707573208736691420c 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
    For a list of contributors, see the accompanying CONTRIBUTORS file.
 
@@ -625,12 +625,28 @@ ui::Window BuildDialog(){
        auto vbox2 = create_dialog_vbox( 0, 4 );
        frame.add(vbox2);
 
+       const char* engine;
+#if defined( WIN32 )
+       engine = g_pGameDescription->getRequiredKeyValue( "engine_win32" );
+#elif defined( __linux__ ) || defined ( __FreeBSD__ )
+       engine = g_pGameDescription->getRequiredKeyValue( "engine_linux" );
+#elif defined( __APPLE__ )
+       engine = g_pGameDescription->getRequiredKeyValue( "engine_macos" );
+#else
+#error "unsupported platform"
+#endif
+       StringOutputStream text( 256 );
+       text << "Select directory, where game executable sits (typically \"" << engine << "\")\n";
+       GtkLabel* label = GTK_LABEL( gtk_label_new( text.c_str() ) );
+       gtk_widget_show( GTK_WIDGET( label ) );
+       gtk_container_add( GTK_CONTAINER( vbox2 ), GTK_WIDGET( label ) );
+
        {
                PreferencesPage page( *this, vbox2 );
                Paths_constructBasicPreferences( page );
        }
 
-       return ui::Window(create_simple_modal_dialog_window( "Engine Path Not Found", m_modal, frame ));
+       return ui::Window(create_simple_modal_dialog_window( "Engine Path Configuration", m_modal, frame ));
 }
 };
 
index efff8a087d8cf594ee033d142fcf42d45e55f6ab..53e3fa80c1f0d35a429d5e32f972cdd5f7de43e5 100644 (file)
@@ -958,20 +958,20 @@ bool PreferencesDialog_isRestartRequired(){
 }
 
 void PreferencesDialog_restartIfRequired(){
-       if ( !g_restart_required.empty() ) {
-               StringOutputStream message( 256 );
+               if ( !g_restart_required.empty() ) {
+                       StringOutputStream message( 256 );
                message << "Preference changes require a restart:\n\n";
 
-               for ( std::vector<const char*>::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i )
-               {
-                       message << ( *i ) << '\n';
-               }
+                       for ( std::vector<const char*>::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i )
+                       {
+                               message << ( *i ) << '\n';
+                       }
 
                message << "\nRestart now?";
 
                auto ret = ui::alert( MainFrame_getWindow(), message.c_str(), "Restart " RADIANT_NAME "?", ui::alert_type::YESNO, ui::alert_icon::Question );
 
-               g_restart_required.clear();
+                       g_restart_required.clear();
 
                if ( ret == ui::alert_response::YES ) {
                        g_GamesDialog.m_bSkipGamePromptOnce = true;
index a7739d4dce474fa6bdae9165e85422097c68d153..7ce4943ad26b3e46d5a528ff01b8f1cfe37208e1 100644 (file)
@@ -270,7 +270,7 @@ std::list<CGameDescription*> mGames;
 
 CGameDialog() :
        m_sGameFile( "" ),
-       m_bGamePrompt( true ),
+       m_bGamePrompt( false ),
        m_bSkipGamePromptOnce( false ),
        m_bForceLogConsole( false ){
 }
@@ -357,13 +357,13 @@ public:
 
 ui::Widget m_notebook{ui::null};
 
-virtual ~PrefsDlg() {
+virtual ~PrefsDlg(){
        if (m_rc_path) {
-               g_string_free( m_rc_path, true );
+       g_string_free( m_rc_path, true );
        }
        if (m_inipath) {
-               g_string_free( m_inipath, true );
-       }
+       g_string_free( m_inipath, true );
+}
 }
 
 /*!
index 282ae0e7993bd7662108ffd904f90cebf16d3002..11ea9cb8aefc372ea52446b24bb0aa6334903640 100644 (file)
@@ -396,10 +396,10 @@ TextureBrowser() :
        m_rmbSelected( false ),
        m_searchedTags( false ),
        m_tags( false ),
+       m_move_started( false ),
        m_uniformTextureSize( 160 ),
        m_uniformTextureMinSize( 48 ),
-       m_hideNonShadersInCommon( true ),
-       m_move_started( false ){
+       m_hideNonShadersInCommon( true ){
 }
 };
 
@@ -888,6 +888,7 @@ void visit( const char* minor, const _QERPlugImageTable& table ) const {
 };
 
 void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* directory ){
+       textureBrowser.m_searchedTags = false;
        if ( TextureBrowser_showWads() ) {
                g_TextureBrowser_currentDirectory = directory;
                TextureBrowser_heightChanged( textureBrowser );
@@ -1535,6 +1536,7 @@ void BuildStoreAvailableTags(   ui::ListStore storeAvailable,
 
 gboolean TextureBrowser_button_press( ui::Widget widget, GdkEventButton* event, TextureBrowser* textureBrowser ){
        if ( event->type == GDK_BUTTON_PRESS ) {
+               gtk_widget_grab_focus( widget );
                if ( event->button == 3 ) {
                        if ( textureBrowser->m_tags ) {
                                textureBrowser->m_rmbSelected = true;
@@ -1612,6 +1614,10 @@ gboolean TextureBrowser_motion( ui::Widget widget, GdkEventMotion *event, Textur
 }
 
 gboolean TextureBrowser_scroll( ui::Widget widget, GdkEventScroll* event, TextureBrowser* textureBrowser ){
+       gtk_widget_grab_focus( widget );
+       if( !gtk_window_is_active( textureBrowser->m_parent ) )
+               gtk_window_present( textureBrowser->m_parent );
+
        if ( event->direction == GDK_SCROLL_UP ) {
                TextureBrowser_MouseWheel( *textureBrowser, true );
        }
index 4edf8344ef48307d0aed0f9d84cba3d8503199e5..c7d1d6cbf1560f01c7637493c3e88c46eceb3bc0 100644 (file)
@@ -765,6 +765,8 @@ void xy_update_xor_rectangle( XYWnd& self, rect_t area ){
 
 gboolean xywnd_button_press( ui::Widget widget, GdkEventButton* event, XYWnd* xywnd ){
        if ( event->type == GDK_BUTTON_PRESS ) {
+               gtk_widget_grab_focus( xywnd->GetWidget() );
+
                if( !xywnd->Active() ){
                        g_pParentWnd->SetActiveXY( xywnd );
                }
@@ -804,6 +806,11 @@ void xywnd_motion( gdouble x, gdouble y, guint state, void* data ){
 }
 
 gboolean xywnd_wheel_scroll( ui::Widget widget, GdkEventScroll* event, XYWnd* xywnd ){
+       gtk_widget_grab_focus( xywnd->GetWidget() );
+       ui::Window window = xywnd->m_parent ? xywnd->m_parent : MainFrame_getWindow();
+       if( !gtk_window_is_active( window ) )
+               gtk_window_present( window );
+
        if( !xywnd->Active() ){
                g_pParentWnd->SetActiveXY( xywnd );
        }
index 7655aa8f25eaa74237be4bc05c449f5bfd058fb7..5d24b3db674e2089b8c73e5b57517d5a91e2f99b 100644 (file)
@@ -266,7 +266,7 @@ skipspace:
                        Error( "Line %i is incomplete\nFile location be: %s\n", scriptline, g_strLoadedFileLocation );
                }
                script->script_p += 2;
-               while ( script->script_p[0] != '*' && script->script_p[1] != '/' )
+               while ( script->script_p[0] != '*' || script->script_p[1] != '/' )
                {
                        if ( *script->script_p == '\n' ) {
                                script->line++;
index 27ae8c31f31d8705d0eb06109ba3323386c69b6d..5aab9d053955c2771af2b8525f0edbf16eeb4405 100644 (file)
@@ -668,7 +668,7 @@ int FloodEntities( tree_t *tree ){
        node_t      *headnode;
        entity_t    *e, *tripped;
        const char  *value;
-       int tripcount;
+       int tripcount = INT_MIN;
 
 
        headnode = tree->headnode;