]> git.rm.cloudns.org Git - xonotic/netradiant.git/commitdiff
Q3map2:
authorGarux <garux@mail.ru>
Wed, 2 Aug 2017 06:21:32 +0000 (09:21 +0300)
committerGarux <garux@mail.ru>
Wed, 2 Aug 2017 06:21:32 +0000 (09:21 +0300)
disable fastnormalize for light: was increasing dirt from arealights, lighting with acute angle

Radiant:

binds...
* QE tool: alt + m1 drag in primitives mode:
click face = clicked faces shear
* m3 in texbro: select texture w/o applying to selection
* `: XYFocusOnSelected
* ctrl + shift + e: Select Connected Entities
misc...
* search in shortcuts list
* edit shortcuts on m1 dbl click
* edit shortcuts fix: could highlight a few rows for editing
* texbro: toggle off hideUnused on loading a tag
* fix of: undo something, select tex in texbro, no redo available
* epsilon in resize brush selector to prevent perpendicular faces pickup
* clone group entity primitives to separate entity on cloneSelectedMakeUnique
* Focus on Selected option in Entity List (focus cam and center xy)
* entity inspector: connected entities walker (select target / targeting / both)(focus)

20 files changed:
libs/mathlib.h
libs/mathlib/mathlib.c
libs/splines/math_matrix.h
radiant/brush.h
radiant/camwindow.cpp
radiant/camwindow.h
radiant/commands.cpp
radiant/entityinspector.cpp
radiant/entitylist.cpp
radiant/mainframe.cpp
radiant/mainframe.h
radiant/map.cpp
radiant/map.h
radiant/patchmanip.cpp
radiant/select.cpp
radiant/select.h
radiant/selection.cpp
radiant/texwindow.cpp
radiant/xywindow.cpp
radiant/xywindow.h

index fb135b8ae0de4d4797f5cdf3eb7f838f6d3e1a86..8ed115d606d7973d6c16bb692974b5c57ad6a956 100644 (file)
@@ -102,12 +102,19 @@ void _CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross );
 // This define affect the precision of VectorNormalize() function only.
 #define MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX 1
 vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out );
-vec_t VectorFastNormalize( const vec3_t in, vec3_t out );
+vec_t VectorFastNormalize_( const vec3_t in, vec3_t out );
 #if MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX
 #define VectorNormalize VectorAccurateNormalize
 #else
-#define VectorNormalize VectorFastNormalize
+#define VectorNormalize VectorFastNormalize_
 #endif
+
+#if 0 //use fastnormalize in a few -light spots
+       #define VectorFastNormalize VectorFastNormalize_
+#else
+       #define VectorFastNormalize VectorNormalize
+#endif
+
 vec_t ColorNormalize( const vec3_t in, vec3_t out );
 void VectorInverse( vec3_t v );
 void VectorPolar( vec3_t v, float radius, float theta, float phi );
index 642f9842e78ce94ad72d53950873fb79a8d67dd5..dbc2a0f2ed1e73db00a5214b12db5f791cf70427 100644 (file)
@@ -179,7 +179,7 @@ vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out ) {
        return (vec_t) length;
 }
 
-vec_t VectorFastNormalize( const vec3_t in, vec3_t out ) {
+vec_t VectorFastNormalize_( const vec3_t in, vec3_t out ) {
 
        // SmileTheory: This is ioquake3's VectorNormalize2
        //              for when accuracy matters less than speed
index 597f1d029085e9c828c330d82275f8970e8139f9..8b653b0ecbece58d1cc50407c91887390390e858 100644 (file)
@@ -84,7 +84,12 @@ ID_INLINE mat3_t::mat3_t() {
 }
 
 ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
-       memcpy( mat, src, sizeof( src ) );
+       //memcpy( mat, src, sizeof( src ) );
+       for( unsigned int i = 0; i < 3; i++ ) {
+               mat[i].x = src[i][0];
+               mat[i].y = src[i][1];
+               mat[i].z = src[i][2];
+       }
 }
 
 ID_INLINE mat3_t::mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ) {
index c467af92110ebd5dae6e81197de2cdd1b5aa40ce..a7229119e723e323d830f8105bc27011ed75afc2 100644 (file)
@@ -2425,6 +2425,34 @@ void forEachLight( const RendererLightCallback& callback ) const {
 }
 };
 
+class BoolSelector : public Selector
+{
+bool m_selected;
+SelectionIntersection m_intersection;
+Selectable* m_selectable;
+public:
+BoolSelector() : m_selected( false ){
+}
+
+void pushSelectable( Selectable& selectable ){
+       m_intersection = SelectionIntersection();
+       m_selectable = &selectable;
+}
+void popSelectable(){
+       if ( m_intersection.valid() ) {
+               m_selected = true;
+       }
+       m_intersection = SelectionIntersection();
+}
+void addIntersection( const SelectionIntersection& intersection ){
+       assign_if_closer( m_intersection, intersection );
+}
+
+bool isSelected(){
+       return m_selected;
+}
+};
+
 class FaceInstance
 {
 Face* m_face;
@@ -2624,7 +2652,9 @@ void selectPlane( Selector& selector, const Line& line, const PlaneCallback& sel
        {
                Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
                double dot = vector3_dot( getFace().plane3().normal(), v );
-               if ( dot <= 0 ) {
+               //globalOutputStream() << dot << "\n";
+               //epsilon to prevent perpendicular faces pickup
+               if ( dot <= 0.005 ) {
                        return;
                }
        }
@@ -2643,7 +2673,8 @@ bool trySelectPlane( const Line& line ){
        for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){
                Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
                double dot = vector3_dot( getFace().plane3().normal(), v );
-               if ( dot <= 0 ) {
+               //epsilon to prevent perpendicular faces pickup
+               if ( dot <= 0.005 ) {
                        return false;
                }
        }
@@ -3020,6 +3051,20 @@ void selectVerticesOnPlanes( SelectionTest& test ){
        }
        while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
 }
+
+void selectVerticesOnTestedFaces( SelectionTest& test ){
+       FaceVertexId faceVertex = m_vertex->m_faceVertex;
+       do
+       {
+               BoolSelector selector;
+               m_faceInstances[faceVertex.getFace()].testSelect( selector, test );
+               if( selector.isSelected() ){
+                       setSelected( true );
+               }
+               faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
+       }
+       while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
+}
 };
 
 class BrushInstanceVisitor
@@ -3486,6 +3531,15 @@ void selectVerticesOnPlanes( SelectionTest& test ){
 }
 
 
+void selectVerticesOnTestedFaces( SelectionTest& test ){
+       test.BeginMesh( localToWorld() );
+
+       for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i ){
+               ( *i ).selectVerticesOnTestedFaces( test );
+       }
+}
+
+
 void transformComponents( const Matrix4& matrix ){
        for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
        {
index 1c782e43ad455c5374961a8465cd032d04294955..99210352c42485a3e7a710d920e7a05555b07f4e 100644 (file)
@@ -1695,20 +1695,22 @@ void GlobalCamera_ResetAngles(){
 
 void GlobalCamera_FocusOnSelected(){
        CamWnd& camwnd = *g_camwnd;
-
+/*
        Vector3 angles( Camera_getAngles( camwnd ) );
        Vector3 radangles( degrees_to_radians( angles[0] ), degrees_to_radians( angles[1] ), degrees_to_radians( angles[2] ) );
        Vector3 viewvector;
        viewvector[0] = cos( radangles[1] ) * cos( radangles[0] );
        viewvector[1] = sin( radangles[1] ) * cos( radangles[0] );
        viewvector[2] = sin( radangles[0] );
-
+*/
        Vector3 camorigin( Camera_getOrigin( camwnd ) );
 
        AABB aabb( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) );
 
        View& view = *( camwnd.getCamera().m_view );
 
+       Vector3 viewvector( -view.GetModelview()[2], -view.GetModelview()[6], -view.GetModelview()[10] );
+
        Plane3 frustumPlanes[4];
        frustumPlanes[0] = plane3_translated( view.getFrustum().left, camorigin - aabb.origin );
        frustumPlanes[1] = plane3_translated( view.getFrustum().right, camorigin - aabb.origin );
@@ -1732,6 +1734,13 @@ void GlobalCamera_FocusOnSelected(){
                        }
                }
        }
+/*
+       globalOutputStream() << viewvector << "\n";
+       globalOutputStream() << view.GetModelview()[0] << " " << view.GetModelview()[1] << " " << view.GetModelview()[2] << " " << view.GetModelview()[3] << "\n"
+        << view.GetModelview()[4] << " " << view.GetModelview()[5] << " " << view.GetModelview()[6] << " " << view.GetModelview()[7] << "\n"
+         << view.GetModelview()[8] << " " << view.GetModelview()[9] << " " << view.GetModelview()[10] << " " << view.GetModelview()[11] << "\n"
+          << view.GetModelview()[12] << " " << view.GetModelview()[13] << " " << view.GetModelview()[14] << " " << view.GetModelview()[15] << "\n";
+*/
        Camera_setOrigin( camwnd, aabb.origin - viewvector * offset );
 }
 
index ce8db6e2538d32f8c49c69511615a3d7bf35bada..146105503193fa399a21f72355b46923a0d059fd 100644 (file)
@@ -50,6 +50,8 @@ void GlobalCamera_Benchmark();
 const Vector3& Camera_getOrigin( CamWnd& camwnd );
 void Camera_setOrigin( CamWnd& camwnd, const Vector3& origin );
 
+void GlobalCamera_FocusOnSelected();
+
 enum
 {
        CAMERA_PITCH = 0, // up / down
index f608ea49709348fbc4574bdb7d062ccd7312b18f..0b802451e8f3be6a97186035b865f094a4d4f0eb 100644 (file)
@@ -226,6 +226,11 @@ void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){
        if ( !gtk_tree_selection_get_selected( sel, &model, &iter ) ) {
                return;
        }
+       if ( dialog.m_waiting_for_key ) {
+               // unhighlight highlit
+               dialog.m_waiting_for_key = false;
+               gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+       }
        dialog.m_command_iter = iter;
        dialog.m_model = model;
 
@@ -239,6 +244,14 @@ void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){
        dialog.m_waiting_for_key = true;
 }
 
+gboolean accelerator_tree_butt_press( GtkWidget* widget, GdkEventButton* event, gpointer dialogptr ){
+       if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) {
+               accelerator_edit_button_clicked( 0, dialogptr );
+               return TRUE;
+       }
+       return FALSE;
+}
+
 gboolean accelerator_window_key_press( GtkWidget *widget, GdkEventKey *event, gpointer dialogptr ){
        command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
 
@@ -413,7 +426,9 @@ void DoCommandListDlg(){
                        GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
                        dialog.m_list = GTK_TREE_VIEW( view );
 
-                       gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), false ); // annoying
+                       //gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), false ); // annoying
+
+                       g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( accelerator_tree_butt_press ), &dialog );
 
                        {
                                GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
index 4905cf0141c7b46deb37fbe620cb21d3d47cb35c..201a4f12b370567688e580b01da5d8691a688d3d 100644 (file)
@@ -49,6 +49,7 @@
 #include <gtk/gtkscrolledwindow.h>
 #include <gtk/gtkentry.h>
 #include <gtk/gtkcombobox.h>
+#include <gtk/gtkstock.h>
 
 
 #include "os/path.h"
@@ -78,6 +79,8 @@
 #include "textureentry.h"
 #include "groupdialog.h"
 
+#include "select.h"
+
 GtkEntry* numeric_entry_new(){
        GtkEntry* entry = GTK_ENTRY( gtk_entry_new() );
        gtk_widget_show( GTK_WIDGET( entry ) );
@@ -778,6 +781,8 @@ GtkCheckButton* g_entitySpawnflagsCheck[MAX_FLAGS];
 GtkEntry* g_entityKeyEntry;
 GtkEntry* g_entityValueEntry;
 
+GtkToggleButton* g_focusToggleButton;
+
 GtkListStore* g_entlist_store;
 GtkListStore* g_entprops_store;
 const EntityClass* g_current_flags = 0;
@@ -1411,6 +1416,21 @@ static gint EntityInspector_hideWindowKB( GtkWidget* widget, GdkEventKey* event,
        return FALSE;
 }
 
+void EntityInspector_selectTargeting( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( true, false, focus );
+}
+
+void EntityInspector_selectTargets( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( false, true, focus );
+}
+
+void EntityInspector_selectConnected( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( true, true, focus );
+}
+
 GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
        GtkWidget* vbox = gtk_vbox_new( FALSE, 2 );
        gtk_widget_show( vbox );
@@ -1619,22 +1639,60 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
                                }
 
                                {
-                                       GtkBox* hbox = GTK_BOX( gtk_hbox_new( TRUE, 4 ) );
+                                       GtkBox* hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) );
                                        gtk_widget_show( GTK_WIDGET( hbox ) );
                                        gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 );
 
                                        {
                                                GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Clear All" ) );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
                                                gtk_widget_show( GTK_WIDGET( button ) );
                                                g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearAllKeyValues ), 0 );
                                                gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
                                        }
                                        {
                                                GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Delete Key" ) );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
                                                gtk_widget_show( GTK_WIDGET( button ) );
                                                g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearKeyValue ), 0 );
                                                gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
                                        }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targeting entities" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargeting ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( ">" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targets" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargets ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<->" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select connected entities" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectConnected ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               GtkWidget* button = gtk_toggle_button_new();
+                                               GtkImage* image = GTK_IMAGE( gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_SMALL_TOOLBAR ) );
+                                               gtk_widget_show( GTK_WIDGET( image ) );
+                                               gtk_container_add( GTK_CONTAINER( button ), GTK_WIDGET( image ) );
+                                               gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE );
+                                               GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS );
+                                               gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 );
+                                               gtk_widget_set_tooltip_text( button, "Focus on Selected" );
+                                               gtk_widget_show( button );
+                                               g_focusToggleButton = GTK_TOGGLE_BUTTON( button );
+                                       }
                                }
                        }
 
index 4fdc5b4ea6e83f0f20c45085aa4c0141f3336be2..7f93b44ff84a05108ea5bd07724147c03a0c1522 100644 (file)
@@ -27,6 +27,8 @@
 #include <gtk/gtktreeview.h>
 #include <gtk/gtktreeselection.h>
 #include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkvbox.h>
 
 #include "string/string.h"
 #include "scenelib.h"
@@ -42,6 +44,8 @@
 
 #include "treemodel.h"
 
+#include "mainframe.h"
+
 void RedrawEntityList();
 typedef FreeCaller<RedrawEntityList> RedrawEntityListCaller;
 
@@ -63,6 +67,7 @@ IdleDraw m_idleDraw;
 WindowPositionTracker m_positionTracker;
 
 GtkWindow* m_window;
+GtkWidget* m_check;
 GtkTreeView* m_tree_view;
 GraphTreeModel* m_tree_model;
 bool m_selection_disabled;
@@ -157,6 +162,9 @@ static gboolean entitylist_tree_select( GtkTreeSelection *selection, GtkTreeMode
                getEntityList().m_selection_disabled = true;
                selectable->setSelected( path_currently_selected == FALSE );
                getEntityList().m_selection_disabled = false;
+               if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( getEntityList().m_check ) ) ){
+                       FocusAllViews();
+               }
                return TRUE;
        }
 
@@ -295,8 +303,14 @@ void EntityList_constructWindow( GtkWindow* main_window ){
        getEntityList().m_window = window;
 
        {
+               GtkVBox* vbox = GTK_VBOX( gtk_vbox_new( FALSE, 0 ) );
+               gtk_container_set_border_width( GTK_CONTAINER( vbox ), 0 );
+               gtk_widget_show( GTK_WIDGET( vbox ) );
+               gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) );
+
                GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
-               gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) );
+               //gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) );
+               gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 );
 
                {
                        GtkWidget* view = gtk_tree_view_new();
@@ -319,6 +333,13 @@ void EntityList_constructWindow( GtkWindow* main_window ){
                        gtk_container_add( GTK_CONTAINER( scr ), view );
                        getEntityList().m_tree_view = GTK_TREE_VIEW( view );
                }
+               {
+                       GtkWidget* check = gtk_check_button_new_with_label( "Focus on Selected" );
+                       gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check ), FALSE );
+                       gtk_widget_show( check );
+                       gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
+                       getEntityList().m_check = check;
+               }
        }
 
        EntityList_ConnectSignals( getEntityList().m_tree_view );
index 1c956db0b9cf341a3f8b610f7af4b4a01095439f..5e7ccc16f00e9265cd0a7a9a18b8a46e4b044279 100644 (file)
@@ -1163,6 +1163,12 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                         && selectable->isSelected() ) {
                        return false;
                }
+               if( doMakeUnique && instance.childSelected() ){
+                       NodeSmartReference clone( Node_Clone_Selected( path.top() ) );
+                       Map_gatherNamespaced( clone );
+                       Node_getTraversable( path.parent().get() )->insert( clone );
+                       return false;
+               }
        }
 
        return true;
@@ -1916,6 +1922,7 @@ GtkMenuItem* create_edit_menu(){
 //     }
        create_menu_item_with_mnemonic( menu, "Select All Of Type", "SelectAllOfType" );
        create_menu_item_with_mnemonic( menu, "_Expand Selection To Entities", "ExpandSelectionToEntities" );
+       create_menu_item_with_mnemonic( menu, "Select Connected Entities", "SelectConnectedEntities" );
 
        menu_separator( menu );
        create_menu_item_with_mnemonic( menu, "Pre_ferences...", "Preferences" );
@@ -1994,6 +2001,7 @@ GtkMenuItem* create_view_menu( MainFrame::EViewStyle style ){
                        create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "NextView" );
                }
 
+               create_menu_item_with_mnemonic( orthographic_menu, "Focus on Selected", "XYFocusOnSelected" );
                create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "CenterXYView" );
                menu_separator( orthographic_menu );
                create_menu_item_with_mnemonic( orthographic_menu, "_XY 100%", "Zoom100" );
@@ -3393,6 +3401,10 @@ void Maximize_View(){
                g_maximizeview.toggle();
 }
 
+void FocusAllViews(){
+       XY_Centralize(); //using centralizing here, not focusing function
+       GlobalCamera_FocusOnSelected();
+}
 
 #include "preferencesystem.h"
 #include "stringio.h"
@@ -3431,6 +3443,7 @@ void MainFrame_Construct(){
        GlobalCommands_insert( "SelectInside", FreeCaller<Select_Inside>() );
        GlobalCommands_insert( "SelectTouching", FreeCaller<Select_Touching>() );
        GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller<Scene_ExpandSelectionToEntities>(), Accelerator( 'E', (GdkModifierType)GDK_SHIFT_MASK ) );
+       GlobalCommands_insert( "SelectConnectedEntities", FreeCaller<SelectConnectedEntities>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
        GlobalCommands_insert( "Preferences", FreeCaller<PreferencesDialog_showDialog>(), Accelerator( 'P' ) );
 
        GlobalCommands_insert( "ToggleConsole", FreeCaller<Console_ToggleShow>(), Accelerator( 'O' ) );
index 1d9cfad7fc6d218dbcaf6e4b474c3e5cc131e210..93c9ef5961e24056075c256032660ed27e4ce7cb 100644 (file)
@@ -277,4 +277,6 @@ void XYWindowMouseDown_disconnect( MouseEventHandlerId id );
 
 extern GtkWidget* g_page_entity;
 
+void FocusAllViews();
+
 #endif
index 73fceb5d449f01bec55f10222f3429887c0ccb2a..93d8a67f6c777bd2467ea1c0dda449903666e5a9 100644 (file)
@@ -734,6 +734,50 @@ scene::Node& Node_Clone( scene::Node& node ){
        return clone;
 }
 
+bool Node_instanceSelected( scene::Node& node );
+
+class CloneAllSelected : public scene::Traversable::Walker
+{
+mutable scene::Path m_path;
+public:
+CloneAllSelected( scene::Node& root )
+       : m_path( makeReference( root ) ){
+}
+bool pre( scene::Node& node ) const {
+       if ( node.isRoot() ) {
+               return false;
+       }
+
+       if( Node_instanceSelected( node ) ){
+               m_path.push( makeReference( node_clone( node ) ) );
+               m_path.top().get().IncRef();
+       }
+
+       return true;
+}
+void post( scene::Node& node ) const {
+       if ( node.isRoot() ) {
+               return;
+       }
+
+       if( Node_instanceSelected( node ) ){
+               Node_getTraversable( m_path.parent() )->insert( m_path.top() );
+
+               m_path.top().get().DecRef();
+               m_path.pop();
+       }
+}
+};
+
+scene::Node& Node_Clone_Selected( scene::Node& node ){
+       scene::Node& clone = node_clone( node );
+       scene::Traversable* traversable = Node_getTraversable( node );
+       if ( traversable != 0 ) {
+               traversable->traverse( CloneAllSelected( clone ) );
+       }
+       return clone;
+}
+
 
 typedef std::map<CopiedString, std::size_t> EntityBreakdown;
 
index a359d46159a676405df4523b4961573c41f1d10a..6e705f6c89a061db1708688a2ed5bac97b7bf07e 100644 (file)
@@ -125,6 +125,7 @@ bool Map_Save();
 bool Map_SaveAs();
 
 scene::Node& Node_Clone( scene::Node& node );
+scene::Node& Node_Clone_Selected( scene::Node& node );
 
 void DoMapInfo();
 
index be74d66a40b4f1975cc919544a2c74fd8f0207ca..ef22c53c2392b7de7a119da16c238bc80e01687d 100644 (file)
@@ -841,8 +841,10 @@ void Patch_registerCommands(){
        GlobalCommands_insert( "PatchDeleteFirstRow", FreeCaller<Patch_DeleteFirstRow>() );
        GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller<Patch_DeleteLastRow>(), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) );
        GlobalCommands_insert( "InvertCurve", FreeCaller<Patch_Invert>(), Accelerator( 'I', (GdkModifierType)GDK_CONTROL_MASK ) );
-       GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
-       GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       //GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
+       GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>() );
+       //GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>() );
        GlobalCommands_insert( "SmoothRows", FreeCaller<Patch_SmoothRows>(), Accelerator( 'W', (GdkModifierType)GDK_CONTROL_MASK ) );
        GlobalCommands_insert( "SmoothCols", FreeCaller<Patch_SmoothCols>(), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
        GlobalCommands_insert( "MatrixTranspose", FreeCaller<Patch_Transpose>(), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
index 1de2c1d07d12d77031903368fa75174db1e40a0b..651397ea10377afd7e7c75ca0b963559a98a25e6 100644 (file)
@@ -463,6 +463,13 @@ void Select_SetShader( const char* shader ){
        Scene_BrushSetShader_Component_Selected( GlobalSceneGraph(), shader );
 }
 
+void Select_SetShader_Undo( const char* shader ){
+       if ( GlobalSelectionSystem().countSelectedComponents() != 0 || GlobalSelectionSystem().countSelected() != 0 ) {
+               UndoableCommand undo( "textureNameSetSelected" );
+               Select_SetShader( shader );
+       }
+}
+
 void Select_SetTexdef( const TextureProjection& projection ){
        if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
                Scene_BrushSetTexdef_Selected( GlobalSceneGraph(), projection );
@@ -1390,3 +1397,79 @@ void DoScaleDlg(){
 
        gtk_widget_show( GTK_WIDGET( g_scale_dialog.window ) );
 }
+
+
+class EntityGetSelectedPropertyValuesWalker_nonEmpty : public scene::Graph::Walker
+{
+PropertyValues& m_propertyvalues;
+const char *m_prop;
+const NodeSmartReference worldspawn;
+public:
+EntityGetSelectedPropertyValuesWalker_nonEmpty( const char *prop, PropertyValues& propertyvalues )
+       : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+       Entity* entity = Node_getEntity( path.top() );
+       if ( entity != 0 ){
+               if( path.top().get() != worldspawn ){
+                       Selectable* selectable = Instance_getSelectable( instance );
+                       if ( ( selectable != 0 && selectable->isSelected() ) || instance.childSelected() ) {
+                               const char* keyvalue = entity->getKeyValue( m_prop );
+                               if ( !string_empty( keyvalue ) && !propertyvalues_contain( m_propertyvalues, keyvalue ) ) {
+                                       m_propertyvalues.push_back( keyvalue );
+                               }
+                       }
+               }
+               return false;
+       }
+       return true;
+}
+};
+
+void Scene_EntityGetPropertyValues_nonEmpty( scene::Graph& graph, const char *prop, PropertyValues& propertyvalues ){
+       graph.traverse( EntityGetSelectedPropertyValuesWalker_nonEmpty( prop, propertyvalues ) );
+}
+
+#include "preferences.h"
+
+void Select_ConnectedEntities( bool targeting, bool targets, bool focus ){
+       PropertyValues target_propertyvalues;
+       PropertyValues targetname_propertyvalues;
+       const char *target_prop = "target";
+       const char *targetname_prop;
+       if ( g_pGameDescription->mGameType == "doom3" ) {
+               targetname_prop = "name";
+       }
+       else{
+               targetname_prop = "targetname";
+       }
+
+       if( targeting ){
+               Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), targetname_prop, targetname_propertyvalues );
+       }
+       if( targets ){
+               Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), target_prop, target_propertyvalues );
+       }
+
+       if( target_propertyvalues.empty() && targetname_propertyvalues.empty() ){
+               globalErrorStream() << "SelectConnectedEntities: nothing found\n";
+               return;
+       }
+
+       if( !targeting || !targets ){
+               GlobalSelectionSystem().setSelectedAll( false );
+       }
+       if ( targeting && !targetname_propertyvalues.empty() ) {
+               Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), target_prop, targetname_propertyvalues );
+       }
+       if ( targets && !target_propertyvalues.empty() ) {
+               Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), targetname_prop, target_propertyvalues );
+       }
+       if( focus ){
+               FocusAllViews();
+       }
+}
+
+void SelectConnectedEntities(){
+       Select_ConnectedEntities( true, true, false );
+}
index 5a602742fd766e007e412ccce49fa784f97706db..88d25f68abef201c0e8fbba377882f4468d60c71 100644 (file)
@@ -46,11 +46,15 @@ void Selection_MoveUp();
 
 void Select_AllOfType();
 
+void Select_ConnectedEntities( bool targeting, bool targets, bool focus );
+void SelectConnectedEntities();
+
 void DoRotateDlg();
 void DoScaleDlg();
 
 
 void Select_SetShader( const char* shader );
+void Select_SetShader_Undo( const char* shader );
 
 class TextureProjection;
 void Select_SetTexdef( const TextureProjection& projection );
index a08659b4ab61f5f2b4d48355dd90b22d6ed28bca..71c747bf596d2cd993c571a9494f794a0cf9e66a 100644 (file)
@@ -1889,12 +1889,12 @@ bool Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& s
 
 
 #include "brush.h"
-/*
-class TestedBrushPlanesSelectVeritces : public scene::Graph::Walker
+
+class TestedBrushFacesSelectVeritces : public scene::Graph::Walker
 {
 SelectionTest& m_test;
 public:
-TestedBrushPlanesSelectVeritces( SelectionTest& test )
+TestedBrushFacesSelectVeritces( SelectionTest& test )
        : m_test( test ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
@@ -1903,7 +1903,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                if ( selectable != 0 && selectable->isSelected() ) {
                        BrushInstance* brushInstance = Instance_getBrush( instance );
                        if ( brushInstance != 0 ) {
-                               brushInstance->selectVerticesOnPlanes( m_test );
+                               brushInstance->selectVerticesOnTestedFaces( m_test );
                        }
                }
        }
@@ -1911,10 +1911,10 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
 }
 };
 
-void Scene_forEachTestedBrushPlane_selectVertices( scene::Graph& graph, SelectionTest& test ){
-       graph.traverse( TestedBrushPlanesSelectVeritces( test ) );
+void Scene_forEachTestedBrushFace_selectVertices( scene::Graph& graph, SelectionTest& test ){
+       graph.traverse( TestedBrushFacesSelectVeritces( test ) );
 }
-*/
+
 class BrushPlanesSelectVeritces : public scene::Graph::Walker
 {
 SelectionTest& m_test;
@@ -2683,8 +2683,8 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
                                        m_dragSelectable.setSelected( false );
                                }
                                if( deepSelector.best().empty() ){
-                                       //Scene_forEachTestedBrushPlane_selectVertices( GlobalSceneGraph(), test );     //todo? drag clicked face
-                                       Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test );
+                                       Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test );        //drag clicked face
+                                       //Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test );
                                        m_selected = true;
                                }
                        }
index efc5f4327e8c2dca4b6cf2b19e651c8a19a0c072..a9d542bc177a9b01abb494c6814e0692cf4af4a1 100644 (file)
@@ -974,16 +974,15 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){
    By mouse click
    ==============
  */
-void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flags ){
+void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flags, bool texturizeSelection ){
        if ( ( flags & GDK_SHIFT_MASK ) == 0 ) {
                IShader* shader = Texture_At( textureBrowser, mx, my );
                if ( shader != 0 ) {
                        TextureBrowser_SetSelectedShader( textureBrowser, shader->getName() );
                        TextureBrowser_textureSelected( shader->getName() );
 
-                       if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected ) {
-                               UndoableCommand undo( "textureNameSetSelected" );
-                               Select_SetShader( shader->getName() );
+                       if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected && !texturizeSelection ) {
+                               Select_SetShader_Undo( shader->getName() );
                        }
                }
        }
@@ -1025,8 +1024,8 @@ void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){
        textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser );
 }
 
-void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
-       SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, flags );
+void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy, bool texturizeSelection ){
+       SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, flags, texturizeSelection );
 }
 
 void TextureBrowser_Selection_MouseUp( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
@@ -1382,7 +1381,7 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
                if ( event->button == 3 ) {
                        if ( GlobalTextureBrowser().m_tags ) {
                                textureBrowser->m_rmbSelected = true;
-                               TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
+                               TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ), false );
 
                                BuildStoreAssignedTags( textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), textureBrowser );
                                BuildStoreAvailableTags( textureBrowser->m_available_store, textureBrowser->m_assigned_store, textureBrowser->m_all_tags, textureBrowser );
@@ -1398,8 +1397,8 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
                                TextureBrowser_Tracking_MouseDown( *textureBrowser );
                        }
                }
-               else if ( event->button == 1 ) {
-                       TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
+               else if ( event->button == 1 || event->button == 2 ) {
+                       TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ), event->button == 2 );
 
                        if ( GlobalTextureBrowser().m_tags ) {
                                textureBrowser->m_rmbSelected = false;
@@ -1409,7 +1408,6 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
        }
        else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) {
                CopiedString texName = textureBrowser->shader;
-               //const char* sh = texName.c_str();
                char* sh = const_cast<char*>( texName.c_str() );
                char* dir = strrchr( sh, '/' );
                if( dir != NULL ){
@@ -1966,6 +1964,7 @@ void TextureBrowser_searchTags(){
                                TextureDirectory_loadTexture( path.c_str(), name.c_str() );
                        }
                }
+               TextureBrowser_SetHideUnused( g_TextureBrowser, false );
                g_TextureBrowser.m_searchedTags = true;
                g_TextureBrowser_currentDirectory = tags_searched;
 
index 9a1be033098b674ac0b98e939d380e732b14e308..dd0e45a34f3f84e0e4f032dbfa7456bae012b572 100644 (file)
@@ -550,6 +550,20 @@ void XYWnd::ZoomInWithMouse( int pointx, int pointy ){
        }
 }
 
+void XYWnd::FocusOnBounds( AABB& bounds ){
+       SetOrigin( bounds.origin );
+       int nDim1 = ( m_viewType == YZ ) ? 1 : 0;
+       int nDim2 = ( m_viewType == XY ) ? 1 : 2;
+       if( bounds.extents[ nDim1 ] < 128.f )
+               bounds.extents[ nDim1 ] = 128.f;
+       if( bounds.extents[ nDim2 ] < 128.f )
+               bounds.extents[ nDim2 ] = 128.f;
+       float scale1 = Width() / ( 3.f * bounds.extents[ nDim1 ] );
+       float scale2 = Height() / ( 3.f * bounds.extents[ nDim2 ] );
+       SetScale( MIN( scale1, scale2 ) );
+
+}
+
 VIEWTYPE GlobalXYWnd_getCurrentViewType(){
        ASSERT_NOTNULL( g_pParentWnd );
        ASSERT_NOTNULL( g_pParentWnd->ActiveXY() );
@@ -2703,7 +2717,7 @@ void XYWnd::OnEntityCreate( const char* item ){
 
 
 
-void GetFocusPosition( Vector3& position ){
+void GetCenterPosition( Vector3& position ){
        if ( GlobalSelectionSystem().countSelected() != 0 ) {
                Select_GetMid( position );
        }
@@ -2713,15 +2727,15 @@ void GetFocusPosition( Vector3& position ){
        }
 }
 
-void XYWnd_Focus( XYWnd* xywnd ){
+void XYWnd_Centralize( XYWnd* xywnd ){
        Vector3 position;
-       GetFocusPosition( position );
+       GetCenterPosition( position );
        xywnd->PositionView( position );
 }
 
-void XY_Split_Focus(){
+void XY_Split_Centralize(){
        Vector3 position;
-       GetFocusPosition( position );
+       GetCenterPosition( position );
        if ( g_pParentWnd->GetXYWnd() ) {
                g_pParentWnd->GetXYWnd()->PositionView( position );
        }
@@ -2733,10 +2747,52 @@ void XY_Split_Focus(){
        }
 }
 
+void XY_Centralize(){
+       if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
+               // centralize all
+               XY_Split_Centralize();
+               return;
+       }
+
+       XYWnd* xywnd = g_pParentWnd->GetXYWnd();
+       XYWnd_Centralize( xywnd );
+}
+
+
+
+void GetSelectionBbox( AABB& bounds ){
+       if ( GlobalSelectionSystem().countSelected() != 0 ) {
+               Scene_BoundsSelected( GlobalSceneGraph(), bounds );
+       }
+       else
+       {
+               bounds = AABB( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ), Vector3( 128.f, 128.f, 128.f ) );
+       }
+}
+
+void XYWnd_Focus( XYWnd* xywnd ){
+       AABB bounds;
+       GetSelectionBbox( bounds );
+       xywnd->FocusOnBounds( bounds );
+}
+
+void XY_Split_Focus(){
+       AABB bounds;
+       GetSelectionBbox( bounds );
+       if ( g_pParentWnd->GetXYWnd() ) {
+               g_pParentWnd->GetXYWnd()->FocusOnBounds( bounds );
+       }
+       if ( g_pParentWnd->GetXZWnd() ) {
+               g_pParentWnd->GetXZWnd()->FocusOnBounds( bounds );
+       }
+       if ( g_pParentWnd->GetYZWnd() ) {
+               g_pParentWnd->GetYZWnd()->FocusOnBounds( bounds );
+       }
+}
+
 void XY_Focus(){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
-               // cannot do this in a split window
-               // do something else that the user may want here
+               // focus all
                XY_Split_Focus();
                return;
        }
@@ -2745,16 +2801,18 @@ void XY_Focus(){
        XYWnd_Focus( xywnd );
 }
 
+
+
 void XY_TopFrontSide( VIEWTYPE viewtype ){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
                // cannot do this in a split window
                // do something else that the user may want here
-               XY_Split_Focus();
+               XY_Split_Centralize();
                return;
        }
        XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
        xywnd->SetViewType( viewtype );
-       XYWnd_Focus( xywnd );
+       XYWnd_Centralize( xywnd );
 }
 
 void XY_Top(){
@@ -2779,14 +2837,14 @@ void XY_NextView( XYWnd* xywnd ){
        else{
                xywnd->SetViewType( XY );
        }
-       XYWnd_Focus( xywnd );
+       XYWnd_Centralize( xywnd );
 }
 
 void XY_Next(){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
                // cannot do this in a split window
                // do something else that the user may want here
-               XY_Split_Focus();
+               XY_Split_Centralize();
                return;
        }
        XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
@@ -3070,7 +3128,8 @@ void XYWindow_Construct(){
        GlobalCommands_insert( "ViewSide", FreeCaller<XY_Side>(), Accelerator( GDK_KP_Page_Down ) );
        GlobalCommands_insert( "ViewFront", FreeCaller<XY_Front>(), Accelerator( GDK_KP_End ) );
        GlobalCommands_insert( "Zoom100", FreeCaller<XY_Zoom100>() );
-       GlobalCommands_insert( "CenterXYView", FreeCaller<XY_Focus>(), Accelerator( GDK_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       GlobalCommands_insert( "CenterXYView", FreeCaller<XY_Centralize>(), Accelerator( GDK_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       GlobalCommands_insert( "XYFocusOnSelected", FreeCaller<XY_Focus>(), Accelerator( GDK_grave ) );
 
        GlobalPreferenceSystem().registerPreference( "ClipCaulk", BoolImportStringCaller( g_clip_useCaulk ), BoolExportStringCaller( g_clip_useCaulk ) );
 
index a3fbd3019d731982e33c372cc29dfb81671b7213..5c25847d149abce1722c24c248f7954483d93ece 100644 (file)
@@ -129,6 +129,7 @@ guint m_zoom_focusOut;
 void ZoomIn();
 void ZoomOut();
 void ZoomInWithMouse( int pointx, int pointy );
+void FocusOnBounds( AABB& bounds );
 
 void RenderActive();
 void SetActive( bool b ){
@@ -251,6 +252,7 @@ inline void XYWnd_Update( XYWnd& xywnd ){
        xywnd.queueDraw();
 }
 
+void XY_Centralize();
 
 struct xywindow_globals_t
 {