1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "SmartAttributeEditorManager.h" 21 22 #include "CollectionUtils.h" 23 #include "View/MapDocument.h" 24 #include "View/SmartChoiceEditor.h" 25 #include "View/SmartChoiceEditorMatcher.h" 26 #include "View/SmartColorEditor.h" 27 #include "View/SmartDefaultAttributeEditor.h" 28 #include "View/SmartAttributeEditor.h" 29 #include "View/SmartAttributeEditorMatcher.h" 30 #include "View/SmartSpawnflagsEditor.h" 31 32 #include <wx/panel.h> 33 #include <wx/sizer.h> 34 35 namespace TrenchBroom { 36 namespace View { SmartAttributeEditorManager(wxWindow * parent,View::MapDocumentWPtr document)37 SmartAttributeEditorManager::SmartAttributeEditorManager(wxWindow* parent, View::MapDocumentWPtr document) : 38 wxPanel(parent), 39 m_document(document), 40 m_name("") { 41 createEditors(); 42 activateEditor(defaultEditor(), ""); 43 bindObservers(); 44 } 45 ~SmartAttributeEditorManager()46 SmartAttributeEditorManager::~SmartAttributeEditorManager() { 47 unbindObservers(); 48 deactivateEditor(); 49 } 50 switchEditor(const Model::AttributeName & name,const Model::AttributableNodeList & attributables)51 void SmartAttributeEditorManager::switchEditor(const Model::AttributeName& name, const Model::AttributableNodeList& attributables) { 52 EditorPtr editor = selectEditor(name, attributables); 53 activateEditor(editor, name); 54 updateEditor(); 55 } 56 createEditors()57 void SmartAttributeEditorManager::createEditors() { 58 m_editors.push_back(MatcherEditorPair(MatcherPtr(new SmartAttributeEditorKeyMatcher("spawnflags")), 59 EditorPtr(new SmartSpawnflagsEditor(m_document)))); 60 m_editors.push_back(MatcherEditorPair(MatcherPtr(new SmartAttributeEditorKeyMatcher("_color", "_sunlight_color", "_sunlight_color2")), 61 EditorPtr(new SmartColorEditor(m_document)))); 62 m_editors.push_back(MatcherEditorPair(MatcherPtr(new SmartChoiceEditorMatcher()), 63 EditorPtr(new SmartChoiceEditor(m_document)))); 64 m_editors.push_back(MatcherEditorPair(MatcherPtr(new SmartAttributeEditorDefaultMatcher()), 65 EditorPtr(new SmartDefaultAttributeEditor(m_document)))); 66 } 67 bindObservers()68 void SmartAttributeEditorManager::bindObservers() { 69 MapDocumentSPtr document = lock(m_document); 70 document->selectionDidChangeNotifier.addObserver(this, &SmartAttributeEditorManager::selectionDidChange); 71 document->nodesDidChangeNotifier.addObserver(this, &SmartAttributeEditorManager::nodesDidChange); 72 } 73 unbindObservers()74 void SmartAttributeEditorManager::unbindObservers() { 75 if (!expired(m_document)) { 76 MapDocumentSPtr document = lock(m_document); 77 document->selectionDidChangeNotifier.removeObserver(this, &SmartAttributeEditorManager::selectionDidChange); 78 document->nodesDidChangeNotifier.removeObserver(this, &SmartAttributeEditorManager::nodesDidChange); 79 } 80 } 81 selectionDidChange(const Selection & selection)82 void SmartAttributeEditorManager::selectionDidChange(const Selection& selection) { 83 MapDocumentSPtr document = lock(m_document); 84 switchEditor(m_name, document->allSelectedAttributableNodes()); 85 } 86 nodesDidChange(const Model::NodeList & nodes)87 void SmartAttributeEditorManager::nodesDidChange(const Model::NodeList& nodes) { 88 MapDocumentSPtr document = lock(m_document); 89 switchEditor(m_name, document->allSelectedAttributableNodes()); 90 } 91 selectEditor(const Model::AttributeName & name,const Model::AttributableNodeList & attributables) const92 SmartAttributeEditorManager::EditorPtr SmartAttributeEditorManager::selectEditor(const Model::AttributeName& name, const Model::AttributableNodeList& attributables) const { 93 EditorList::const_iterator it, end; 94 for (it = m_editors.begin(), end = m_editors.end(); it != end; ++it) { 95 const MatcherEditorPair& pair = *it; 96 const MatcherPtr matcher = pair.first; 97 if (matcher->matches(name, attributables)) 98 return pair.second; 99 } 100 101 // should never happen 102 assert(false); 103 return defaultEditor(); 104 } 105 106 defaultEditor() const107 SmartAttributeEditorManager::EditorPtr SmartAttributeEditorManager::defaultEditor() const { 108 return m_editors.back().second; 109 } 110 activateEditor(EditorPtr editor,const Model::AttributeName & name)111 void SmartAttributeEditorManager::activateEditor(EditorPtr editor, const Model::AttributeName& name) { 112 if (m_activeEditor != editor || !m_activeEditor->usesName(name)) { 113 deactivateEditor(); 114 m_activeEditor = editor; 115 m_name = name; 116 wxWindow* window = m_activeEditor->activate(this, m_name); 117 118 wxSizer* sizer = new wxBoxSizer(wxVERTICAL); 119 sizer->Add(window, 1, wxEXPAND); 120 SetSizer(sizer); 121 Layout(); 122 } 123 } 124 deactivateEditor()125 void SmartAttributeEditorManager::deactivateEditor() { 126 if (m_activeEditor.get() != NULL) { 127 m_activeEditor->deactivate(); 128 m_activeEditor = EditorPtr(); 129 m_name = ""; 130 } 131 } 132 updateEditor()133 void SmartAttributeEditorManager::updateEditor() { 134 if (m_activeEditor.get() != NULL) { 135 MapDocumentSPtr document = lock(m_document); 136 m_activeEditor->update(document->allSelectedAttributableNodes()); 137 } 138 } 139 } 140 } 141