diff --git a/common/src/Model/ParaxialTexCoordSystem.cpp b/common/src/Model/ParaxialTexCoordSystem.cpp index 46bfca5c1c..8acace712f 100644 --- a/common/src/Model/ParaxialTexCoordSystem.cpp +++ b/common/src/Model/ParaxialTexCoordSystem.cpp @@ -167,14 +167,15 @@ namespace TrenchBroom { // WARNING: the texture plane norm is not the rotation axis of the texture (it's always the absolute axis) // determine the rotation angle from the dot product of the new base axes and the transformed texture axes - float cosX = static_cast(newBaseXAxis.dot(newXAxis)); - assert(!Math::isnan(cosX)); - float radX = std::acos(cosX); - if (crossed(newBaseXAxis, newXAxis).dot(newProjectionAxis) < 0.0) - radX *= -1.0f; + // we prefer the Y axis over the X axis because this usually gives better results on most brushes + float cosY = static_cast(newBaseYAxis.dot(newYAxis)); + assert(!Math::isnan(cosY)); + float radY = std::acos(cosY); + if (crossed(newBaseYAxis, newYAxis).dot(newProjectionAxis) < 0.0) + radY *= -1.0f; // for some reason, when the texture plane normal is the Y axis, we must rotation clockwise - float rad = radX; + float rad = radY; if (newIndex == 4) rad *= -1.0f; diff --git a/common/src/Renderer/MapRenderer.cpp b/common/src/Renderer/MapRenderer.cpp index 43b2687249..90e9b6b5eb 100644 --- a/common/src/Renderer/MapRenderer.cpp +++ b/common/src/Renderer/MapRenderer.cpp @@ -161,6 +161,7 @@ namespace TrenchBroom { document->faceDidChangeNotifier.addObserver(this, &MapRenderer::faceDidChange); document->selectionDidChangeNotifier.addObserver(this, &MapRenderer::selectionDidChange); document->modsDidChangeNotifier.addObserver(this, &MapRenderer::modsDidChange); + document->textureCollectionsDidChangeNotifier.addObserver(this, &MapRenderer::textureCollectionsDidChange); document->entityDefinitionsDidChangeNotifier.addObserver(this, &MapRenderer::entityDefinitionsDidChange); PreferenceManager& prefs = PreferenceManager::instance(); @@ -181,6 +182,7 @@ namespace TrenchBroom { document->faceDidChangeNotifier.removeObserver(this, &MapRenderer::faceDidChange); document->selectionDidChangeNotifier.removeObserver(this, &MapRenderer::selectionDidChange); document->modsDidChangeNotifier.removeObserver(this, &MapRenderer::modsDidChange); + document->textureCollectionsDidChangeNotifier.removeObserver(this, &MapRenderer::textureCollectionsDidChange); document->entityDefinitionsDidChangeNotifier.removeObserver(this, &MapRenderer::entityDefinitionsDidChange); } @@ -283,6 +285,11 @@ namespace TrenchBroom { m_selectedEntityRenderer.reloadModels(); } + void MapRenderer::textureCollectionsDidChange() { + m_unselectedBrushRenderer.invalidate(); + m_selectedBrushRenderer.invalidate(); + } + void MapRenderer::preferenceDidChange(const IO::Path& path) { View::MapDocumentSPtr document = lock(m_document); if (document->isGamePathPreference(path)) { diff --git a/common/src/Renderer/MapRenderer.h b/common/src/Renderer/MapRenderer.h index c7b291f197..4f831e7814 100644 --- a/common/src/Renderer/MapRenderer.h +++ b/common/src/Renderer/MapRenderer.h @@ -79,6 +79,7 @@ namespace TrenchBroom { void selectionDidChange(const Model::SelectionResult& result); void modsDidChange(); void entityDefinitionsDidChange(); + void textureCollectionsDidChange(); void preferenceDidChange(const IO::Path& path); void clearState(); diff --git a/common/src/TrenchBroomApp.cpp b/common/src/TrenchBroomApp.cpp index bc0d336556..70b4804b37 100644 --- a/common/src/TrenchBroomApp.cpp +++ b/common/src/TrenchBroomApp.cpp @@ -65,10 +65,6 @@ namespace TrenchBroom { // we must delete the recent documents here instead of in OnExit because they might still be used by the frame destructors delete m_recentDocuments; m_recentDocuments = NULL; - - // The config manager is deleted before the persistence manager has a chance to save its data. This leads - // to the config manager getting recreated, but not flushed, so we explicitly delete it again here. - delete wxConfig::Set(NULL); } FrameManager* TrenchBroomApp::frameManager() { @@ -242,6 +238,12 @@ namespace TrenchBroom { } } + int TrenchBroomApp::OnRun() { + const int result = wxApp::OnRun(); + DeletePendingObjects(); + return result; + } + void TrenchBroomApp::OnFileNew(wxCommandEvent& event) { newDocument(); } @@ -292,7 +294,7 @@ namespace TrenchBroom { #ifdef __APPLE__ void TrenchBroomApp::OnFileExit(wxCommandEvent& event) { if (m_frameManager->closeAllFrames()) - Exit(); + ExitMainLoop(); } void TrenchBroomApp::OnUpdateUI(wxUpdateUIEvent& event) { diff --git a/common/src/TrenchBroomApp.h b/common/src/TrenchBroomApp.h index 44d40221b8..334b77844f 100644 --- a/common/src/TrenchBroomApp.h +++ b/common/src/TrenchBroomApp.h @@ -63,6 +63,8 @@ namespace TrenchBroom { int OnExit(); void OnUnhandledException(); + int OnRun(); + void OnFileNew(wxCommandEvent& event); void OnFileOpen(wxCommandEvent& event); void OnFileOpenRecent(wxCommandEvent& event); diff --git a/common/src/View/PersistentSplitterWindow.cpp b/common/src/View/PersistentSplitterWindow.cpp index 95b4437ac6..ffa50d76c2 100644 --- a/common/src/View/PersistentSplitterWindow.cpp +++ b/common/src/View/PersistentSplitterWindow.cpp @@ -32,8 +32,7 @@ namespace TrenchBroom { void PersistentSplitterWindow::Save() const { const SplitterWindow* window = Get(); - if (window->m_sashPosition > 0) - SaveValue("SashPosition", window->m_sashPosition); + SaveValue("SashPosition", window->m_sashPosition); } bool PersistentSplitterWindow::Restore() { diff --git a/common/src/View/SplitterWindow.cpp b/common/src/View/SplitterWindow.cpp index 6a5a5150b9..a6f4b53db7 100644 --- a/common/src/View/SplitterWindow.cpp +++ b/common/src/View/SplitterWindow.cpp @@ -49,6 +49,7 @@ namespace TrenchBroom { Bind(wxEVT_MOUSE_CAPTURE_LOST, &SplitterWindow::OnMouseCaptureLost, this); Bind(wxEVT_SIZE, &SplitterWindow::OnSize, this); + Bind(wxEVT_IDLE, &SplitterWindow::OnIdle, this); } void SplitterWindow::splitHorizontally(wxWindow* left, wxWindow* right, const wxSize& leftMin, const wxSize& rightMin) { @@ -178,6 +179,14 @@ namespace TrenchBroom { } } + void SplitterWindow::OnIdle(wxIdleEvent& event) { + if (IsShownOnScreen()) { + Unbind(wxEVT_IDLE, &SplitterWindow::OnIdle, this); + + // if the initial sash position could not be set until now, then it probably cannot be set at all + m_initialSashPosition = -1; + } + } void SplitterWindow::OnSize(wxSizeEvent& event) { updateSashPosition(m_oldSize, event.GetSize()); sizeWindows(); @@ -189,15 +198,10 @@ namespace TrenchBroom { initSashPosition(); if (m_splitMode != SplitMode_Unset) { - if (m_initialSashPosition != -1) { - if (setSashPosition(m_initialSashPosition)) - m_initialSashPosition = -1; - } else { - const wxSize diff = newSize - oldSize; - const int actualDiff = wxRound(m_sashGravity * h(diff)); - if (actualDiff != 0) - setSashPosition(m_sashPosition + actualDiff); - } + const wxSize diff = newSize - oldSize; + const int actualDiff = wxRound(m_sashGravity * h(diff)); + if (actualDiff != 0) + setSashPosition(m_sashPosition + actualDiff); } } @@ -206,7 +210,9 @@ namespace TrenchBroom { setSashPosition(h(m_minSizes[0]) + wxRound(m_sashGravity * (h(m_minSizes[1]) - h(m_minSizes[0]))) + 1); } - bool SplitterWindow::setSashPosition(const int position) { + bool SplitterWindow::setSashPosition(int position) { + if (m_initialSashPosition != -1) + position = m_initialSashPosition; if (position == m_sashPosition) return true; m_sashPosition = position; diff --git a/common/src/View/SplitterWindow.h b/common/src/View/SplitterWindow.h index ee7c93aa54..7beea13e2a 100644 --- a/common/src/View/SplitterWindow.h +++ b/common/src/View/SplitterWindow.h @@ -78,6 +78,7 @@ namespace TrenchBroom { void unsetSashCursor(); wxCursor sizeCursor() const; public: + void OnIdle(wxIdleEvent& event); void OnSize(wxSizeEvent& event); private: void updateSashPosition(const wxSize& oldSize, const wxSize& newSize);