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 "SwitchableMapViewContainer.h"
21 
22 #include "PreferenceManager.h"
23 #include "Preferences.h"
24 #include "Model/PointFile.h"
25 #include "Renderer/MapRenderer.h"
26 #include "View/CyclingMapView.h"
27 #include "View/TwoPaneMapView.h"
28 #include "View/ThreePaneMapView.h"
29 #include "View/FourPaneMapView.h"
30 #include "View/GLContextManager.h"
31 #include "View/Inspector.h"
32 #include "View/MapDocument.h"
33 #include "View/MapViewContainer.h"
34 #include "View/MapViewBar.h"
35 #include "View/MapViewToolBox.h"
36 
37 #include <wx/sizer.h>
38 
39 namespace TrenchBroom {
40     namespace View {
SwitchableMapViewContainer(wxWindow * parent,Logger * logger,MapDocumentWPtr document,GLContextManager & contextManager)41         SwitchableMapViewContainer::SwitchableMapViewContainer(wxWindow* parent, Logger* logger, MapDocumentWPtr document, GLContextManager& contextManager) :
42         wxPanel(parent),
43         m_logger(logger),
44         m_document(document),
45         m_contextManager(contextManager),
46         m_mapViewBar(new MapViewBar(this, m_document)),
47         m_toolBox(new MapViewToolBox(m_document, m_mapViewBar->toolBook())),
48         m_mapRenderer(new Renderer::MapRenderer(m_document)),
49         m_mapView(NULL) {
50             switchToMapView(static_cast<MapViewLayout>(pref(Preferences::MapViewLayout)));
51             bindObservers();
52         }
53 
~SwitchableMapViewContainer()54         SwitchableMapViewContainer::~SwitchableMapViewContainer() {
55             unbindObservers();
56 
57             // we must destroy our children before we destroy our resources because they might still use them in their destructors
58             DestroyChildren();
59 
60             delete m_toolBox;
61             m_toolBox = NULL;
62 
63             delete m_mapRenderer;
64             m_mapRenderer = NULL;
65         }
66 
connectTopWidgets(Inspector * inspector)67         void SwitchableMapViewContainer::connectTopWidgets(Inspector* inspector) {
68             inspector->connectTopWidgets(m_mapViewBar);
69         }
70 
viewportHasFocus() const71         bool SwitchableMapViewContainer::viewportHasFocus() const {
72             return m_mapView != NULL && m_mapView->isCurrent();
73         }
74 
switchToMapView(const MapViewLayout viewId)75         void SwitchableMapViewContainer::switchToMapView(const MapViewLayout viewId) {
76             if (m_mapView != NULL) {
77                 m_mapView->Destroy();
78                 m_mapView = NULL;
79             }
80 
81             switch (viewId) {
82                 case MapViewLayout_1Pane:
83                     m_mapView = new CyclingMapView(this, m_logger, m_document, *m_toolBox, *m_mapRenderer, m_contextManager, CyclingMapView::View_ALL);
84                     break;
85                 case MapViewLayout_2Pane:
86                     m_mapView = new TwoPaneMapView(this, m_logger, m_document, *m_toolBox, *m_mapRenderer, m_contextManager);
87                     break;
88                 case MapViewLayout_3Pane:
89                     m_mapView = new ThreePaneMapView(this, m_logger, m_document, *m_toolBox, *m_mapRenderer, m_contextManager);
90                     break;
91                 case MapViewLayout_4Pane:
92                     m_mapView = new FourPaneMapView(this, m_logger, m_document, *m_toolBox, *m_mapRenderer, m_contextManager);
93                     break;
94             }
95 
96             wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
97             sizer->Add(m_mapViewBar, 0, wxEXPAND);
98             sizer->Add(m_mapView, 1, wxEXPAND);
99             SetSizer(sizer);
100             Layout();
101 
102             m_mapView->SetFocus();
103         }
104 
anyToolActive() const105         bool SwitchableMapViewContainer::anyToolActive() const {
106             return createComplexBrushToolActive() || clipToolActive() || rotateObjectsToolActive() || vertexToolActive();
107         }
108 
deactivateTool()109         void SwitchableMapViewContainer::deactivateTool() {
110             m_toolBox->deactivateAllTools();
111         }
112 
createComplexBrushToolActive() const113         bool SwitchableMapViewContainer::createComplexBrushToolActive() const {
114             return m_toolBox->createComplexBrushToolActive();
115         }
116 
canToggleCreateComplexBrushTool() const117         bool SwitchableMapViewContainer::canToggleCreateComplexBrushTool() const {
118             return true;
119         }
120 
toggleCreateComplexBrushTool()121         void SwitchableMapViewContainer::toggleCreateComplexBrushTool() {
122             m_toolBox->toggleCreateComplexBrushTool();
123         }
124 
clipToolActive() const125         bool SwitchableMapViewContainer::clipToolActive() const {
126             return m_toolBox->clipToolActive();
127         }
128 
canToggleClipTool() const129         bool SwitchableMapViewContainer::canToggleClipTool() const {
130             return clipToolActive() || lock(m_document)->selectedNodes().hasOnlyBrushes();
131         }
132 
toggleClipTool()133         void SwitchableMapViewContainer::toggleClipTool() {
134             m_toolBox->toggleClipTool();
135         }
136 
rotateObjectsToolActive() const137         bool SwitchableMapViewContainer::rotateObjectsToolActive() const {
138             return m_toolBox->rotateObjectsToolActive();
139         }
140 
canToggleRotateObjectsTool() const141         bool SwitchableMapViewContainer::canToggleRotateObjectsTool() const {
142             return rotateObjectsToolActive() || lock(m_document)->hasSelectedNodes();
143         }
144 
toggleRotateObjectsTool()145         void SwitchableMapViewContainer::toggleRotateObjectsTool() {
146             m_toolBox->toggleRotateObjectsTool();
147         }
148 
vertexToolActive() const149         bool SwitchableMapViewContainer::vertexToolActive() const {
150             return m_toolBox->vertexToolActive();
151         }
152 
canToggleVertexTool() const153         bool SwitchableMapViewContainer::canToggleVertexTool() const {
154             return vertexToolActive() || lock(m_document)->selectedNodes().hasOnlyBrushes();
155         }
156 
toggleVertexTool()157         void SwitchableMapViewContainer::toggleVertexTool() {
158             m_toolBox->toggleVertexTool();
159         }
160 
canMoveCameraToNextTracePoint() const161         bool SwitchableMapViewContainer::canMoveCameraToNextTracePoint() const {
162             MapDocumentSPtr document = lock(m_document);
163             if (!document->isPointFileLoaded())
164                 return false;
165 
166             Model::PointFile* pointFile = document->pointFile();
167             return pointFile->hasNextPoint();
168         }
169 
canMoveCameraToPreviousTracePoint() const170         bool SwitchableMapViewContainer::canMoveCameraToPreviousTracePoint() const {
171             MapDocumentSPtr document = lock(m_document);
172             if (!document->isPointFileLoaded())
173                 return false;
174 
175             Model::PointFile* pointFile = document->pointFile();
176             return pointFile->hasPreviousPoint();
177         }
178 
moveCameraToNextTracePoint()179         void SwitchableMapViewContainer::moveCameraToNextTracePoint() {
180             MapDocumentSPtr document = lock(m_document);
181             assert(document->isPointFileLoaded());
182 
183             m_mapView->moveCameraToCurrentTracePoint();
184 
185             Model::PointFile* pointFile = document->pointFile();
186             pointFile->advance();
187         }
188 
moveCameraToPreviousTracePoint()189         void SwitchableMapViewContainer::moveCameraToPreviousTracePoint() {
190             MapDocumentSPtr document = lock(m_document);
191             assert(document->isPointFileLoaded());
192 
193             Model::PointFile* pointFile = document->pointFile();
194             pointFile->retreat();
195 
196             m_mapView->moveCameraToCurrentTracePoint();
197         }
198 
canMaximizeCurrentView() const199         bool SwitchableMapViewContainer::canMaximizeCurrentView() const {
200             return m_mapView->canMaximizeCurrentView();
201         }
202 
currentViewMaximized() const203         bool SwitchableMapViewContainer::currentViewMaximized() const {
204             return m_mapView->currentViewMaximized();
205         }
206 
toggleMaximizeCurrentView()207         void SwitchableMapViewContainer::toggleMaximizeCurrentView() {
208             m_mapView->toggleMaximizeCurrentView();
209         }
210 
bindObservers()211         void SwitchableMapViewContainer::bindObservers() {
212             m_toolBox->refreshViewsNotifier.addObserver(this, &SwitchableMapViewContainer::refreshViews);
213         }
214 
unbindObservers()215         void SwitchableMapViewContainer::unbindObservers() {
216             m_toolBox->refreshViewsNotifier.removeObserver(this, &SwitchableMapViewContainer::refreshViews);
217         }
218 
refreshViews(Tool * tool)219         void SwitchableMapViewContainer::refreshViews(Tool* tool) {
220             m_mapView->Refresh();
221         }
222 
doGetIsCurrent() const223         bool SwitchableMapViewContainer::doGetIsCurrent() const {
224             return m_mapView->isCurrent();
225         }
226 
doSetToolBoxDropTarget()227         void SwitchableMapViewContainer::doSetToolBoxDropTarget() {
228             m_mapView->setToolBoxDropTarget();
229         }
230 
doClearDropTarget()231         void SwitchableMapViewContainer::doClearDropTarget() {
232             m_mapView->clearDropTarget();
233         }
234 
doCanSelectTall()235         bool SwitchableMapViewContainer::doCanSelectTall() {
236             return m_mapView->canSelectTall();
237         }
238 
doSelectTall()239         void SwitchableMapViewContainer::doSelectTall() {
240             m_mapView->selectTall();
241         }
242 
doCanFlipObjects() const243         bool SwitchableMapViewContainer::doCanFlipObjects() const {
244             return m_mapView->canFlipObjects();
245         }
246 
doFlipObjects(const Math::Direction direction)247         void SwitchableMapViewContainer::doFlipObjects(const Math::Direction direction) {
248             m_mapView->flipObjects(direction);
249         }
250 
doGetPasteObjectsDelta(const BBox3 & bounds,const BBox3 & referenceBounds) const251         Vec3 SwitchableMapViewContainer::doGetPasteObjectsDelta(const BBox3& bounds, const BBox3& referenceBounds) const {
252             return m_mapView->pasteObjectsDelta(bounds, referenceBounds);
253         }
254 
doFocusCameraOnSelection(const bool animate)255         void SwitchableMapViewContainer::doFocusCameraOnSelection(const bool animate) {
256             m_mapView->focusCameraOnSelection(animate);
257         }
258 
doMoveCameraToPosition(const Vec3 & position,const bool animate)259         void SwitchableMapViewContainer::doMoveCameraToPosition(const Vec3& position, const bool animate) {
260             m_mapView->moveCameraToPosition(position, animate);
261         }
262 
doMoveCameraToCurrentTracePoint()263         void SwitchableMapViewContainer::doMoveCameraToCurrentTracePoint() {
264             m_mapView->moveCameraToCurrentTracePoint();
265         }
266 
doFlashSelection()267         void SwitchableMapViewContainer::doFlashSelection() {
268             m_mapView->flashSelection();
269         }
270     }
271 }
272