4 // Handlers for events relating to the display of a survey.
6 // Copyright (C) 2000-2002,2005 Mark R. Shinwell
7 // Copyright (C) 2001,2003,2004,2005,2006,2011,2012,2014,2015,2016 Olly Betts
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "guicontrol.h"
30 #include <wx/confbase.h>
32 const int DISPLAY_SHIFT
= 10;
33 const double FLYFREE_SHIFT
= 0.2;
34 const double ROTATE_STEP
= 2.0;
36 GUIControl::GUIControl()
40 m_ReverseControls
= false;
41 m_LastDrag
= drag_NONE
;
44 void GUIControl::SetView(GfxCore
* view
)
49 bool GUIControl::MouseDown() const
51 return (dragging
!= NO_DRAG
);
54 void GUIControl::HandleTilt(wxPoint point
)
56 // Handle a mouse movement during tilt mode.
58 // wxGTK (at least) fails to update the cursor while dragging.
59 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY
);
61 int dy
= point
.y
- m_DragStart
.y
;
63 if (m_ReverseControls
!= m_View
->GetPerspective()) dy
= -dy
;
65 m_View
->TiltCave(Double(dy
) * 0.36);
69 m_View
->ForceRefresh();
72 void GUIControl::HandleTranslate(wxPoint point
)
74 // Handle a mouse movement during translation mode.
76 // wxGTK (at least) fails to update the cursor while dragging.
77 m_View
->UpdateCursor(GfxCore::CURSOR_DRAGGING_HAND
);
79 int dx
= point
.x
- m_DragStart
.x
;
80 int dy
= point
.y
- m_DragStart
.y
;
82 if (m_ReverseControls
) {
87 if (m_View
->GetPerspective())
88 m_View
->MoveViewer(0, -dy
* .1, dx
* .1);
90 m_View
->TranslateCave(dx
, dy
);
95 void GUIControl::HandleScaleRotate(wxPoint point
)
97 // Handle a mouse movement during scale/rotate mode.
99 // wxGTK (at least) fails to update the cursor while dragging.
100 m_View
->UpdateCursor(GfxCore::CURSOR_ZOOM_ROTATE
);
104 if (m_ScaleRotateLock
== lock_NONE
) {
105 // Dragging to scale or rotate but we've not decided which yet.
106 dx
= point
.x
- m_DragRealStart
.x
;
107 dy
= point
.y
- m_DragRealStart
.y
;
110 dx
= point
.x
- m_DragStart
.x
;
111 dy
= point
.y
- m_DragStart
.y
;
116 if (dx2
+ dy2
< threshold
) return;
118 switch (m_ScaleRotateLock
) {
121 m_ScaleRotateLock
= lock_ROTATE
;
122 // m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
124 m_ScaleRotateLock
= lock_SCALE
;
125 // m_View->UpdateCursor(GfxCore::CURSOR_ZOOM);
129 if (dx2
>= 8 * dy2
) {
130 m_ScaleRotateLock
= lock_ROTATE
;
131 // m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
135 if (dy2
>= 8 * dx2
) {
136 m_ScaleRotateLock
= lock_SCALE
;
137 // m_View->UpdateCursor(GfxCore::CURSOR_ZOOM);
142 if (m_ScaleRotateLock
== lock_ROTATE
) {
148 if (m_ReverseControls
) {
153 if (m_View
->GetPerspective()) {
154 if (dy
) m_View
->MoveViewer(-dy
* .1, 0, 0);
157 if (dy
) m_View
->SetScale(m_View
->GetScale() * pow(1.06, 0.08 * dy
));
158 // left/right => rotate.
159 if (dx
) m_View
->TurnCave(Double(dx
) * -0.36);
160 if (dx
|| dy
) m_View
->ForceRefresh();
166 void GUIControl::HandleTiltRotate(wxPoint point
)
168 // Handle a mouse movement during tilt/rotate mode.
169 if (m_View
->IsExtendedElevation()) return;
171 // wxGTK (at least) fails to update the cursor while dragging.
172 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY
);
174 int dx
= point
.x
- m_DragStart
.x
;
175 int dy
= point
.y
- m_DragStart
.y
;
177 if (m_ReverseControls
!= m_View
->GetPerspective()) {
182 // left/right => rotate, up/down => tilt.
183 // Make tilt less sensitive than rotate as that feels better.
184 m_View
->TurnCave(Double(dx
) * -0.36);
185 m_View
->TiltCave(Double(dy
) * 0.18);
187 m_View
->ForceRefresh();
192 void GUIControl::HandleRotate(wxPoint point
)
194 // Handle a mouse movement during rotate mode.
195 if (m_View
->IsExtendedElevation()) return;
197 // wxGTK (at least) fails to update the cursor while dragging.
198 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY
);
200 int dx
= point
.x
- m_DragStart
.x
;
201 int dy
= point
.y
- m_DragStart
.y
;
203 if (m_ReverseControls
!= m_View
->GetPerspective()) {
208 // left/right => rotate.
209 m_View
->TurnCave(Double(dx
) * -0.36);
211 m_View
->ForceRefresh();
216 void GUIControl::RestoreCursor()
218 if (m_View
->HereIsReal()) {
219 m_View
->UpdateCursor(GfxCore::CURSOR_POINTING_HAND
);
221 m_View
->UpdateCursor(GfxCore::CURSOR_DEFAULT
);
225 void GUIControl::HandleNonDrag(const wxPoint
& point
) {
226 if (m_View
->IsFullScreen()) {
227 if (m_View
->FullScreenModeShowingMenus()) {
229 m_View
->FullScreenModeShowMenus(false);
232 m_View
->FullScreenModeShowMenus(true);
236 if (m_View
->CheckHitTestGrid(point
, false)) {
237 m_View
->UpdateCursor(GfxCore::CURSOR_POINTING_HAND
);
238 } else if (m_View
->PointWithinScaleBar(point
)) {
239 m_View
->UpdateCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE
);
240 } else if (m_View
->PointWithinCompass(point
)) {
241 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY
);
242 } else if (m_View
->PointWithinClino(point
)) {
243 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY
);
250 // Mouse event handling methods
253 void GUIControl::OnMouseMove(wxMouseEvent
& event
)
255 // Mouse motion event handler.
256 if (!m_View
->HasData()) return;
258 // Ignore moves which don't change the position.
259 if (event
.GetPosition() == m_DragStart
) {
263 static long timestamp
= LONG_MIN
;
264 if (dragging
!= NO_DRAG
&& m_ScaleRotateLock
!= lock_NONE
&&
265 timestamp
!= LONG_MIN
) {
266 // If no motion for a second, reset the direction lock.
267 if (event
.GetTimestamp() - timestamp
>= 1000) {
268 m_ScaleRotateLock
= lock_NONE
;
269 m_DragRealStart
= m_DragStart
;
273 timestamp
= event
.GetTimestamp();
275 wxPoint
point(event
.GetPosition());
277 // Check hit-test grid (only if no buttons are pressed).
278 if (!event
.LeftIsDown() && !event
.MiddleIsDown() && !event
.RightIsDown()) {
279 HandleNonDrag(point
);
282 // Update coordinate display if in plan view,
283 // or altitude if in elevation view.
284 m_View
->SetCoords(point
);
288 switch (m_LastDrag
) {
290 // Drag in heading indicator.
291 m_View
->SetCompassFromPoint(point
);
294 // Drag in clinometer.
295 m_View
->SetClinoFromPoint(point
);
298 m_View
->SetScaleBarFromOffset(point
.x
- m_DragLast
.x
);
301 if (event
.ControlDown()) {
302 HandleTiltRotate(point
);
304 HandleScaleRotate(point
);
308 m_View
->SetZoomBox(m_DragStart
, point
, !event
.ShiftDown(), event
.ControlDown());
311 // Shouldn't happen?! FIXME: assert or something.
319 HandleTranslate(point
);
328 void GUIControl::OnLButtonDown(wxMouseEvent
& event
)
330 if (m_View
->HasData()) {
331 m_DragStart
= m_DragRealStart
= event
.GetPosition();
333 if (m_View
->PointWithinCompass(m_DragStart
)) {
334 m_LastDrag
= drag_COMPASS
;
335 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY
);
336 } else if (m_View
->PointWithinClino(m_DragStart
)) {
337 m_LastDrag
= drag_ELEV
;
338 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY
);
339 } else if (m_View
->PointWithinScaleBar(m_DragStart
)) {
340 m_LastDrag
= drag_SCALE
;
341 m_View
->UpdateCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE
);
342 } else if (event
.ShiftDown()) {
343 m_LastDrag
= drag_ZOOM
;
344 m_View
->UpdateCursor(GfxCore::CURSOR_ZOOM
);
346 if (event
.ControlDown() && !m_View
->IsExtendedElevation()) {
347 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY
);
349 m_View
->UpdateCursor(GfxCore::CURSOR_ZOOM_ROTATE
);
352 m_LastDrag
= drag_MAIN
;
353 m_ScaleRotateLock
= lock_NONE
;
356 // We need to release and recapture for the cursor to update (noticed
358 if (dragging
!= NO_DRAG
) m_View
->ReleaseMouse();
359 m_View
->CaptureMouse();
361 dragging
= LEFT_DRAG
;
365 void GUIControl::OnLButtonUp(wxMouseEvent
& event
)
367 if (m_View
->HasData()) {
368 if (dragging
!= LEFT_DRAG
)
371 if (event
.MiddleIsDown()) {
372 if (m_LastDrag
== drag_ZOOM
)
373 m_View
->UnsetZoomBox();
374 OnMButtonDown(event
);
378 if (event
.RightIsDown()) {
379 if (m_LastDrag
== drag_ZOOM
)
380 m_View
->UnsetZoomBox();
381 OnRButtonDown(event
);
385 if (m_LastDrag
== drag_ZOOM
) {
389 m_View
->ReleaseMouse();
391 m_LastDrag
= drag_NONE
;
394 m_View
->DragFinished();
396 if (event
.GetPosition() == m_DragRealStart
) {
398 m_View
->CheckHitTestGrid(m_DragStart
, true);
401 HandleNonDrag(event
.GetPosition());
406 void GUIControl::OnMButtonDown(wxMouseEvent
& event
)
408 if (m_View
->HasData() && !m_View
->IsExtendedElevation()) {
409 m_DragStart
= event
.GetPosition();
411 m_View
->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY
);
413 if (dragging
!= NO_DRAG
) {
414 if (m_LastDrag
== drag_ZOOM
)
415 m_View
->UnsetZoomBox();
416 // We need to release and recapture for the cursor to update
417 // (noticed with wxGTK).
418 m_View
->ReleaseMouse();
420 m_View
->CaptureMouse();
421 dragging
= MIDDLE_DRAG
;
425 void GUIControl::OnMButtonUp(wxMouseEvent
& event
)
427 if (m_View
->HasData()) {
428 if (dragging
!= MIDDLE_DRAG
)
431 if (event
.LeftIsDown()) {
432 OnLButtonDown(event
);
436 if (event
.RightIsDown()) {
437 OnRButtonDown(event
);
442 m_View
->ReleaseMouse();
443 m_View
->DragFinished();
449 void GUIControl::OnRButtonDown(wxMouseEvent
& event
)
451 if (m_View
->HasData()) {
452 if (dragging
!= NO_DRAG
) {
453 if (m_LastDrag
== drag_ZOOM
)
454 m_View
->UnsetZoomBox();
455 // We need to release and recapture for the cursor to update
456 // (noticed with wxGTK).
457 m_View
->ReleaseMouse();
461 if (m_View
->HandleRClick(event
.GetPosition()))
464 m_DragStart
= event
.GetPosition();
466 m_View
->UpdateCursor(GfxCore::CURSOR_DRAGGING_HAND
);
468 m_View
->CaptureMouse();
469 dragging
= RIGHT_DRAG
;
473 void GUIControl::OnRButtonUp(wxMouseEvent
& event
)
475 if (dragging
!= RIGHT_DRAG
)
478 if (event
.LeftIsDown()) {
479 OnLButtonDown(event
);
483 if (event
.MiddleIsDown()) {
484 OnMButtonDown(event
);
488 m_LastDrag
= drag_NONE
;
489 m_View
->ReleaseMouse();
495 m_View
->DragFinished();
498 void GUIControl::OnMouseWheel(wxMouseEvent
& event
) {
499 int dy
= event
.GetWheelRotation();
500 if (m_View
->GetPerspective()) {
501 m_View
->MoveViewer(-dy
, 0, 0);
503 m_View
->SetScale(m_View
->GetScale() * pow(1.06, -0.04 * dy
));
504 m_View
->ForceRefresh();
508 void GUIControl::OnDisplayOverlappingNames()
510 m_View
->ToggleOverlappingNames();
513 void GUIControl::OnDisplayOverlappingNamesUpdate(wxUpdateUIEvent
& cmd
)
515 cmd
.Enable(m_View
->HasData() && m_View
->ShowingStationNames());
516 cmd
.Check(m_View
->ShowingOverlappingNames());
519 void GUIControl::OnColourByDepth()
521 if (m_View
->ColouringBy() == COLOUR_BY_DEPTH
) {
522 m_View
->SetColourBy(COLOUR_BY_NONE
);
524 m_View
->SetColourBy(COLOUR_BY_DEPTH
);
528 void GUIControl::OnColourByDate()
530 if (m_View
->ColouringBy() == COLOUR_BY_DATE
) {
531 m_View
->SetColourBy(COLOUR_BY_NONE
);
533 m_View
->SetColourBy(COLOUR_BY_DATE
);
537 void GUIControl::OnColourByError()
539 if (m_View
->ColouringBy() == COLOUR_BY_ERROR
) {
540 m_View
->SetColourBy(COLOUR_BY_NONE
);
542 m_View
->SetColourBy(COLOUR_BY_ERROR
);
546 void GUIControl::OnColourByHError()
548 if (m_View
->ColouringBy() == COLOUR_BY_H_ERROR
) {
549 m_View
->SetColourBy(COLOUR_BY_NONE
);
551 m_View
->SetColourBy(COLOUR_BY_H_ERROR
);
555 void GUIControl::OnColourByVError()
557 if (m_View
->ColouringBy() == COLOUR_BY_V_ERROR
) {
558 m_View
->SetColourBy(COLOUR_BY_NONE
);
560 m_View
->SetColourBy(COLOUR_BY_V_ERROR
);
564 void GUIControl::OnColourByGradient()
566 if (m_View
->ColouringBy() == COLOUR_BY_GRADIENT
) {
567 m_View
->SetColourBy(COLOUR_BY_NONE
);
569 m_View
->SetColourBy(COLOUR_BY_GRADIENT
);
573 void GUIControl::OnColourByLength()
575 if (m_View
->ColouringBy() == COLOUR_BY_LENGTH
) {
576 m_View
->SetColourBy(COLOUR_BY_NONE
);
578 m_View
->SetColourBy(COLOUR_BY_LENGTH
);
582 void GUIControl::OnColourBySurvey()
584 if (m_View
->ColouringBy() == COLOUR_BY_SURVEY
) {
585 m_View
->SetColourBy(COLOUR_BY_NONE
);
587 m_View
->SetColourBy(COLOUR_BY_SURVEY
);
591 void GUIControl::OnColourByStyle()
593 if (m_View
->ColouringBy() == COLOUR_BY_STYLE
) {
594 m_View
->SetColourBy(COLOUR_BY_NONE
);
596 m_View
->SetColourBy(COLOUR_BY_STYLE
);
600 void GUIControl::OnColourByUpdate(wxUpdateUIEvent
& cmd
)
602 cmd
.Enable(m_View
->HasData());
605 void GUIControl::OnColourByDepthUpdate(wxUpdateUIEvent
& cmd
)
607 cmd
.Enable(m_View
->HasData());
608 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_DEPTH
);
611 void GUIControl::OnColourByDateUpdate(wxUpdateUIEvent
& cmd
)
613 cmd
.Enable(m_View
->HasData());
614 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_DATE
);
617 void GUIControl::OnColourByErrorUpdate(wxUpdateUIEvent
& cmd
)
619 cmd
.Enable(m_View
->HasData());
620 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_ERROR
);
623 void GUIControl::OnColourByHErrorUpdate(wxUpdateUIEvent
& cmd
)
625 cmd
.Enable(m_View
->HasData());
626 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_H_ERROR
);
629 void GUIControl::OnColourByVErrorUpdate(wxUpdateUIEvent
& cmd
)
631 cmd
.Enable(m_View
->HasData());
632 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_V_ERROR
);
635 void GUIControl::OnColourByGradientUpdate(wxUpdateUIEvent
& cmd
)
637 cmd
.Enable(m_View
->HasData());
638 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_GRADIENT
);
641 void GUIControl::OnColourByLengthUpdate(wxUpdateUIEvent
& cmd
)
643 cmd
.Enable(m_View
->HasData());
644 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_LENGTH
);
647 void GUIControl::OnColourBySurveyUpdate(wxUpdateUIEvent
& cmd
)
649 cmd
.Enable(m_View
->HasData());
650 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_SURVEY
);
653 void GUIControl::OnColourByStyleUpdate(wxUpdateUIEvent
& cmd
)
655 cmd
.Enable(m_View
->HasData());
656 cmd
.Check(m_View
->ColouringBy() == COLOUR_BY_STYLE
);
659 void GUIControl::OnShowCrosses()
661 m_View
->ToggleCrosses();
664 void GUIControl::OnShowCrossesUpdate(wxUpdateUIEvent
& cmd
)
666 cmd
.Enable(m_View
->HasData());
667 cmd
.Check(m_View
->ShowingCrosses());
670 void GUIControl::OnShowStationNames()
672 m_View
->ToggleStationNames();
675 void GUIControl::OnShowStationNamesUpdate(wxUpdateUIEvent
& cmd
)
677 cmd
.Enable(m_View
->HasData());
678 cmd
.Check(m_View
->ShowingStationNames());
681 void GUIControl::OnShowSurveyLegs()
683 m_View
->ToggleUndergroundLegs();
686 void GUIControl::OnShowSurveyLegsUpdate(wxUpdateUIEvent
& cmd
)
688 cmd
.Enable(m_View
->HasData() && m_View
->HasUndergroundLegs());
689 cmd
.Check(m_View
->ShowingUndergroundLegs());
692 void GUIControl::OnHideSplays()
694 m_View
->SetSplaysMode(SHOW_HIDE
);
697 void GUIControl::OnShowSplaysDashed()
699 m_View
->SetSplaysMode(SHOW_DASHED
);
702 void GUIControl::OnShowSplaysFaded()
704 m_View
->SetSplaysMode(SHOW_FADED
);
707 void GUIControl::OnShowSplaysNormal()
709 m_View
->SetSplaysMode(SHOW_NORMAL
);
712 void GUIControl::OnSplaysUpdate(wxUpdateUIEvent
& cmd
)
714 cmd
.Enable(m_View
->HasData() && m_View
->HasSplays());
717 void GUIControl::OnHideSplaysUpdate(wxUpdateUIEvent
& cmd
)
719 cmd
.Enable(m_View
->HasData() && m_View
->HasSplays());
720 cmd
.Check(m_View
->ShowingSplaysMode() == SHOW_HIDE
);
723 void GUIControl::OnShowSplaysDashedUpdate(wxUpdateUIEvent
& cmd
)
725 cmd
.Enable(m_View
->HasData() && m_View
->HasSplays());
726 cmd
.Check(m_View
->ShowingSplaysMode() == SHOW_DASHED
);
729 void GUIControl::OnShowSplaysFadedUpdate(wxUpdateUIEvent
& cmd
)
731 cmd
.Enable(m_View
->HasData() && m_View
->HasSplays());
732 cmd
.Check(m_View
->ShowingSplaysMode() == SHOW_FADED
);
735 void GUIControl::OnShowSplaysNormalUpdate(wxUpdateUIEvent
& cmd
)
737 cmd
.Enable(m_View
->HasData() && m_View
->HasSplays());
738 cmd
.Check(m_View
->ShowingSplaysMode() == SHOW_NORMAL
);
741 void GUIControl::OnHideDupes() {
742 m_View
->SetDupesMode(SHOW_HIDE
);
745 void GUIControl::OnShowDupesDashed() {
746 m_View
->SetDupesMode(SHOW_DASHED
);
749 void GUIControl::OnShowDupesFaded() {
750 m_View
->SetDupesMode(SHOW_FADED
);
753 void GUIControl::OnShowDupesNormal() {
754 m_View
->SetDupesMode(SHOW_NORMAL
);
757 void GUIControl::OnDupesUpdate(wxUpdateUIEvent
& cmd
) {
758 cmd
.Enable(m_View
->HasData() && m_View
->HasDupes());
761 void GUIControl::OnHideDupesUpdate(wxUpdateUIEvent
& cmd
) {
762 cmd
.Enable(m_View
->HasData() && m_View
->HasDupes());
763 cmd
.Check(m_View
->ShowingDupesMode() == SHOW_HIDE
);
766 void GUIControl::OnShowDupesDashedUpdate(wxUpdateUIEvent
& cmd
) {
767 cmd
.Enable(m_View
->HasData() && m_View
->HasDupes());
768 cmd
.Check(m_View
->ShowingDupesMode() == SHOW_DASHED
);
771 void GUIControl::OnShowDupesFadedUpdate(wxUpdateUIEvent
& cmd
) {
772 cmd
.Enable(m_View
->HasData() && m_View
->HasDupes());
773 cmd
.Check(m_View
->ShowingDupesMode() == SHOW_FADED
);
776 void GUIControl::OnShowDupesNormalUpdate(wxUpdateUIEvent
& cmd
) {
777 cmd
.Enable(m_View
->HasData() && m_View
->HasDupes());
778 cmd
.Check(m_View
->ShowingDupesMode() == SHOW_NORMAL
);
781 void GUIControl::OnMoveEast()
783 m_View
->TurnCaveTo(90.0);
784 m_View
->ForceRefresh();
787 void GUIControl::OnMoveEastUpdate(wxUpdateUIEvent
& cmd
)
789 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation() && m_View
->GetCompassValue() != 90.0);
792 void GUIControl::OnMoveNorth()
794 m_View
->TurnCaveTo(0.0);
795 m_View
->ForceRefresh();
798 void GUIControl::OnMoveNorthUpdate(wxUpdateUIEvent
& cmd
)
800 cmd
.Enable(m_View
->HasData() && m_View
->GetCompassValue() != 0.0);
803 void GUIControl::OnMoveSouth()
805 m_View
->TurnCaveTo(180.0);
806 m_View
->ForceRefresh();
809 void GUIControl::OnMoveSouthUpdate(wxUpdateUIEvent
& cmd
)
811 cmd
.Enable(m_View
->HasData() && m_View
->GetCompassValue() != 180.0);
814 void GUIControl::OnMoveWest()
816 m_View
->TurnCaveTo(270.0);
817 m_View
->ForceRefresh();
820 void GUIControl::OnMoveWestUpdate(wxUpdateUIEvent
& cmd
)
822 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation() && m_View
->GetCompassValue() != 270.0);
825 void GUIControl::OnToggleRotation()
827 m_View
->ToggleRotation();
830 void GUIControl::OnToggleRotationUpdate(wxUpdateUIEvent
& cmd
)
832 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation());
833 cmd
.Check(m_View
->HasData() && m_View
->IsRotating());
836 void GUIControl::OnReverseControls()
838 m_ReverseControls
= !m_ReverseControls
;
841 void GUIControl::OnReverseControlsUpdate(wxUpdateUIEvent
& cmd
)
843 cmd
.Enable(m_View
->HasData());
844 cmd
.Check(m_ReverseControls
);
847 void GUIControl::OnReverseDirectionOfRotation()
849 m_View
->ReverseRotation();
852 void GUIControl::OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent
& cmd
)
854 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation());
857 void GUIControl::OnStepOnceAnticlockwise(bool accel
)
859 if (m_View
->GetPerspective()) {
860 m_View
->TurnCave(accel
? -5.0 * ROTATE_STEP
: -ROTATE_STEP
);
862 m_View
->TurnCave(accel
? 5.0 * ROTATE_STEP
: ROTATE_STEP
);
864 m_View
->ForceRefresh();
867 void GUIControl::OnStepOnceClockwise(bool accel
)
869 if (m_View
->GetPerspective()) {
870 m_View
->TurnCave(accel
? 5.0 * ROTATE_STEP
: ROTATE_STEP
);
872 m_View
->TurnCave(accel
? -5.0 * ROTATE_STEP
: -ROTATE_STEP
);
874 m_View
->ForceRefresh();
877 void GUIControl::OnDefaults()
882 void GUIControl::OnDefaultsUpdate(wxUpdateUIEvent
& cmd
)
884 cmd
.Enable(m_View
->HasData());
887 void GUIControl::OnElevation()
889 // Switch to elevation view.
891 m_View
->SwitchToElevation();
894 void GUIControl::OnElevationUpdate(wxUpdateUIEvent
& cmd
)
896 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation() && !m_View
->ShowingElevation());
899 void GUIControl::OnHigherViewpoint(bool accel
)
901 // Raise the viewpoint.
902 if (m_View
->GetPerspective()) {
903 m_View
->TiltCave(accel
? 5.0 * ROTATE_STEP
: ROTATE_STEP
);
905 m_View
->TiltCave(accel
? -5.0 * ROTATE_STEP
: -ROTATE_STEP
);
907 m_View
->ForceRefresh();
910 void GUIControl::OnLowerViewpoint(bool accel
)
912 // Lower the viewpoint.
913 if (m_View
->GetPerspective()) {
914 m_View
->TiltCave(accel
? -5.0 * ROTATE_STEP
: -ROTATE_STEP
);
916 m_View
->TiltCave(accel
? 5.0 * ROTATE_STEP
: ROTATE_STEP
);
918 m_View
->ForceRefresh();
921 void GUIControl::OnPlan()
923 // Switch to plan view.
924 m_View
->SwitchToPlan();
927 void GUIControl::OnPlanUpdate(wxUpdateUIEvent
& cmd
)
929 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation() && !m_View
->ShowingPlan());
932 void GUIControl::OnShiftDisplayDown(bool accel
)
934 if (m_View
->GetPerspective())
935 m_View
->MoveViewer(0, accel
? 5 * FLYFREE_SHIFT
: FLYFREE_SHIFT
, 0);
937 m_View
->TranslateCave(0, accel
? 5 * DISPLAY_SHIFT
: DISPLAY_SHIFT
);
940 void GUIControl::OnShiftDisplayLeft(bool accel
)
942 if (m_View
->GetPerspective())
943 m_View
->MoveViewer(0, 0, accel
? 5 * FLYFREE_SHIFT
: FLYFREE_SHIFT
);
945 m_View
->TranslateCave(accel
? -5 * DISPLAY_SHIFT
: -DISPLAY_SHIFT
, 0);
948 void GUIControl::OnShiftDisplayRight(bool accel
)
950 if (m_View
->GetPerspective())
951 m_View
->MoveViewer(0, 0, accel
? -5 * FLYFREE_SHIFT
: -FLYFREE_SHIFT
);
953 m_View
->TranslateCave(accel
? 5 * DISPLAY_SHIFT
: DISPLAY_SHIFT
, 0);
956 void GUIControl::OnShiftDisplayUp(bool accel
)
958 if (m_View
->GetPerspective())
959 m_View
->MoveViewer(0, accel
? -5 * FLYFREE_SHIFT
: -FLYFREE_SHIFT
, 0);
961 m_View
->TranslateCave(0, accel
? -5 * DISPLAY_SHIFT
: -DISPLAY_SHIFT
);
964 void GUIControl::OnZoomIn(bool accel
)
966 // Increase the scale.
968 if (m_View
->GetPerspective()) {
969 m_View
->MoveViewer(accel
? 5 * FLYFREE_SHIFT
: FLYFREE_SHIFT
, 0, 0);
971 m_View
->SetScale(m_View
->GetScale() * (accel
? 1.1236 : 1.06));
972 m_View
->ForceRefresh();
976 void GUIControl::OnZoomOut(bool accel
)
978 // Decrease the scale.
980 if (m_View
->GetPerspective()) {
981 m_View
->MoveViewer(accel
? -5 * FLYFREE_SHIFT
: -FLYFREE_SHIFT
, 0, 0);
983 m_View
->SetScale(m_View
->GetScale() / (accel
? 1.1236 : 1.06));
984 m_View
->ForceRefresh();
988 void GUIControl::OnToggleScalebar()
990 m_View
->ToggleScaleBar();
993 void GUIControl::OnToggleScalebarUpdate(wxUpdateUIEvent
& cmd
)
995 cmd
.Enable(m_View
->HasData());
996 cmd
.Check(m_View
->ShowingScaleBar());
999 void GUIControl::OnToggleColourKey()
1001 m_View
->ToggleColourKey();
1004 void GUIControl::OnToggleColourKeyUpdate(wxUpdateUIEvent
& cmd
)
1006 cmd
.Enable(m_View
->HasData() && m_View
->ColouringBy() != COLOUR_BY_NONE
);
1007 cmd
.Check(m_View
->ShowingColourKey());
1010 void GUIControl::OnViewCompass()
1012 m_View
->ToggleCompass();
1015 void GUIControl::OnViewCompassUpdate(wxUpdateUIEvent
& cmd
)
1017 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation());
1018 cmd
.Check(m_View
->ShowingCompass());
1021 void GUIControl::OnViewClino()
1023 m_View
->ToggleClino();
1026 void GUIControl::OnViewClinoUpdate(wxUpdateUIEvent
& cmd
)
1028 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation());
1029 cmd
.Check(m_View
->ShowingClino());
1032 void GUIControl::OnShowSurface()
1034 m_View
->ToggleSurfaceLegs();
1037 void GUIControl::OnShowSurfaceUpdate(wxUpdateUIEvent
& cmd
)
1039 cmd
.Enable(m_View
->HasData() && m_View
->HasSurfaceLegs());
1040 cmd
.Check(m_View
->ShowingSurfaceLegs());
1043 void GUIControl::OnShowEntrances()
1045 m_View
->ToggleEntrances();
1048 void GUIControl::OnShowEntrancesUpdate(wxUpdateUIEvent
& cmd
)
1050 cmd
.Enable(m_View
->HasData() && (m_View
->GetNumEntrances() > 0));
1051 cmd
.Check(m_View
->ShowingEntrances());
1054 void GUIControl::OnShowFixedPts()
1056 m_View
->ToggleFixedPts();
1059 void GUIControl::OnShowFixedPtsUpdate(wxUpdateUIEvent
& cmd
)
1061 cmd
.Enable(m_View
->HasData() && (m_View
->GetNumFixedPts() > 0));
1062 cmd
.Check(m_View
->ShowingFixedPts());
1065 void GUIControl::OnShowExportedPts()
1067 m_View
->ToggleExportedPts();
1070 void GUIControl::OnShowExportedPtsUpdate(wxUpdateUIEvent
& cmd
)
1072 cmd
.Enable(m_View
->HasData() && (m_View
->GetNumExportedPts() > 0));
1073 cmd
.Check(m_View
->ShowingExportedPts());
1076 void GUIControl::OnViewGrid()
1078 m_View
->ToggleGrid();
1081 void GUIControl::OnViewGridUpdate(wxUpdateUIEvent
& cmd
)
1083 cmd
.Enable(m_View
->HasData());
1084 cmd
.Check(m_View
->ShowingGrid());
1087 void GUIControl::OnIndicatorsUpdate(wxUpdateUIEvent
& cmd
)
1089 cmd
.Enable(m_View
->HasData());
1092 void GUIControl::OnViewPerspective()
1094 m_View
->TogglePerspective();
1095 // Force update of coordinate display.
1096 if (m_View
->GetPerspective()) {
1097 m_View
->MoveViewer(0, 0, 0);
1099 m_View
->ClearCoords();
1103 void GUIControl::OnViewPerspectiveUpdate(wxUpdateUIEvent
& cmd
)
1105 cmd
.Enable(m_View
->HasData() && !m_View
->IsExtendedElevation());
1106 cmd
.Check(m_View
->GetPerspective());
1109 void GUIControl::OnViewSmoothShading()
1111 m_View
->ToggleSmoothShading();
1114 void GUIControl::OnViewSmoothShadingUpdate(wxUpdateUIEvent
& cmd
)
1116 cmd
.Enable(m_View
->HasData());
1117 cmd
.Check(m_View
->GetSmoothShading());
1120 void GUIControl::OnViewTextured()
1122 m_View
->ToggleTextured();
1125 void GUIControl::OnViewTexturedUpdate(wxUpdateUIEvent
& cmd
)
1127 cmd
.Enable(m_View
->HasData());
1128 cmd
.Check(m_View
->GetTextured());
1131 void GUIControl::OnViewFog()
1133 m_View
->ToggleFog();
1136 void GUIControl::OnViewFogUpdate(wxUpdateUIEvent
& cmd
)
1138 cmd
.Enable(m_View
->HasData());
1139 cmd
.Check(m_View
->GetFog());
1142 void GUIControl::OnViewSmoothLines()
1144 m_View
->ToggleAntiAlias();
1147 void GUIControl::OnViewSmoothLinesUpdate(wxUpdateUIEvent
& cmd
)
1149 cmd
.Enable(m_View
->HasData());
1150 cmd
.Check(m_View
->GetAntiAlias());
1153 void GUIControl::OnToggleMetric()
1155 m_View
->ToggleMetric();
1157 wxConfigBase::Get()->Write(wxT("metric"), m_View
->GetMetric());
1158 wxConfigBase::Get()->Flush();
1161 void GUIControl::OnToggleMetricUpdate(wxUpdateUIEvent
& cmd
)
1163 cmd
.Enable(m_View
->HasData());
1164 cmd
.Check(m_View
->GetMetric());
1167 void GUIControl::OnToggleDegrees()
1169 m_View
->ToggleDegrees();
1171 wxConfigBase::Get()->Write(wxT("degrees"), m_View
->GetDegrees());
1172 wxConfigBase::Get()->Flush();
1175 void GUIControl::OnToggleDegreesUpdate(wxUpdateUIEvent
& cmd
)
1177 cmd
.Enable(m_View
->HasData());
1178 cmd
.Check(m_View
->GetDegrees());
1181 void GUIControl::OnTogglePercent()
1183 m_View
->TogglePercent();
1185 wxConfigBase::Get()->Write(wxT("percent"), m_View
->GetPercent());
1186 wxConfigBase::Get()->Flush();
1189 void GUIControl::OnTogglePercentUpdate(wxUpdateUIEvent
& cmd
)
1191 cmd
.Enable(m_View
->HasData());
1192 cmd
.Check(m_View
->GetPercent());
1195 void GUIControl::OnToggleTubes()
1197 m_View
->ToggleTubes();
1200 void GUIControl::OnToggleTubesUpdate(wxUpdateUIEvent
& cmd
)
1202 cmd
.Enable(m_View
->HasData() && m_View
->HasTubes());
1203 cmd
.Check(m_View
->GetTubes());
1206 void GUIControl::OnCancelDistLine()
1208 m_View
->ClearTreeSelection();
1211 void GUIControl::OnCancelDistLineUpdate(wxUpdateUIEvent
& cmd
)
1213 cmd
.Enable(m_View
->ShowingMeasuringLine());
1216 void GUIControl::OnKeyPress(wxKeyEvent
&e
)
1218 if (!m_View
->HasData() ||
1219 (e
.GetModifiers() &~ (wxMOD_CONTROL
|wxMOD_SHIFT
))) {
1220 // Pass on the event if there's no survey data, or if any modifier keys
1221 // other than Ctrl and Shift are pressed.
1226 // The changelog says this is meant to keep animation going while keys are
1227 // pressed, but that happens anyway (on linux at least - perhaps it helps
1228 // on windows?) FIXME : check!
1229 //bool refresh = m_View->Animate();
1231 switch (e
.GetKeyCode()) {
1233 if (m_View
->CanLowerViewpoint() && !m_View
->IsExtendedElevation())
1234 OnLowerViewpoint(e
.GetModifiers() == wxMOD_SHIFT
);
1236 case '\'': case '@': case '"': // both shifted forms - US and UK kbd
1237 if (m_View
->CanRaiseViewpoint() && !m_View
->IsExtendedElevation())
1238 OnHigherViewpoint(e
.GetModifiers() == wxMOD_SHIFT
);
1241 if (!m_View
->IsExtendedElevation() && !m_View
->IsRotating())
1242 OnStepOnceAnticlockwise(e
.GetModifiers() == wxMOD_SHIFT
);
1245 if (!m_View
->IsExtendedElevation() && !m_View
->IsRotating())
1246 OnStepOnceClockwise(e
.GetModifiers() == wxMOD_SHIFT
);
1249 OnZoomIn(e
.GetModifiers() == wxMOD_SHIFT
);
1252 OnZoomOut(e
.GetModifiers() == wxMOD_SHIFT
);
1261 if (!m_View
->IsExtendedElevation())
1265 if (!m_View
->IsExtendedElevation())
1269 if (!m_View
->IsExtendedElevation())
1270 m_View
->RotateFaster(e
.GetModifiers() == wxMOD_SHIFT
);
1273 if (!m_View
->IsExtendedElevation())
1274 m_View
->RotateSlower(e
.GetModifiers() == wxMOD_SHIFT
);
1277 if (!m_View
->IsExtendedElevation())
1278 OnReverseDirectionOfRotation();
1281 if (!m_View
->IsExtendedElevation() && !m_View
->ShowingPlan())
1285 if (!m_View
->IsExtendedElevation() && !m_View
->ShowingElevation())
1289 OnDisplayOverlappingNames();
1292 if (e
.GetModifiers() == 0)
1296 if (e
.GetModifiers() == 0) {
1297 // For compatibility with older versions.
1298 if (!m_View
->IsExtendedElevation() && !m_View
->IsRotating())
1299 m_View
->StartRotation();
1303 if (e
.GetModifiers() == 0) {
1304 if (!m_View
->IsExtendedElevation())
1309 if ((e
.GetModifiers() &~ wxMOD_SHIFT
) == wxMOD_CONTROL
) {
1310 if (!m_View
->IsExtendedElevation() && !m_View
->IsRotating())
1311 OnStepOnceAnticlockwise(e
.GetModifiers() == wxMOD_SHIFT
);
1313 OnShiftDisplayLeft(e
.GetModifiers() == wxMOD_SHIFT
);
1317 if ((e
.GetModifiers() &~ wxMOD_SHIFT
) == wxMOD_CONTROL
) {
1318 if (!m_View
->IsExtendedElevation() && !m_View
->IsRotating())
1319 OnStepOnceClockwise(e
.GetModifiers() == wxMOD_SHIFT
);
1321 OnShiftDisplayRight(e
.GetModifiers() == wxMOD_SHIFT
);
1325 if ((e
.GetModifiers() &~ wxMOD_SHIFT
) == wxMOD_CONTROL
) {
1326 if (m_View
->CanRaiseViewpoint() && !m_View
->IsExtendedElevation())
1327 OnHigherViewpoint(e
.GetModifiers() == wxMOD_SHIFT
);
1329 OnShiftDisplayUp(e
.GetModifiers() == wxMOD_SHIFT
);
1333 if ((e
.GetModifiers() &~ wxMOD_SHIFT
) == wxMOD_CONTROL
) {
1334 if (m_View
->CanLowerViewpoint() && !m_View
->IsExtendedElevation())
1335 OnLowerViewpoint(e
.GetModifiers() == wxMOD_SHIFT
);
1337 OnShiftDisplayDown(e
.GetModifiers() == wxMOD_SHIFT
);
1341 if (e
.GetModifiers() == 0) {
1342 if (m_View
->ShowingMeasuringLine()) {
1344 } else if (m_View
->IsFullScreen()) {
1345 // Cancel full-screen mode on "Escape" if it isn't cancelling
1346 // the measuring line.
1347 m_View
->FullScreenMode();
1352 if (e
.GetModifiers() == 0)
1353 m_View
->ToggleFatFinger();
1356 if (e
.GetModifiers() == 0)
1357 m_View
->ToggleHitTestDebug();
1360 if (e
.GetModifiers() == 0) {
1363 if (wxTheAssertHandler
)
1364 wxTheAssertHandler
= NULL
;
1366 wxSetDefaultAssertHandler();
1367 if (wxTheAssertHandler
)
1368 msg
= wxT("Assertions enabled");
1370 msg
= wxT("Assertions disabled");
1372 msg
= wxT("wxWidgets was built without assertions");
1374 wxMessageBox(msg
, wxT("Aven Debug"), wxOK
| wxICON_INFORMATION
);
1379 if (e
.GetModifiers() == 0) {
1380 m_View
->InvalidateAllLists();
1381 m_View
->ForceRefresh();
1385 if (e
.GetModifiers() == 0)
1386 m_View
->ToggleRenderStats();
1392 //if (refresh) m_View->ForceRefresh();
1395 void GUIControl::OnViewFullScreenUpdate(wxUpdateUIEvent
& cmd
)
1397 cmd
.Check(m_View
->IsFullScreen());
1400 void GUIControl::OnViewFullScreen()
1402 m_View
->FullScreenMode();
1405 void GUIControl::OnViewBoundingBoxUpdate(wxUpdateUIEvent
& cmd
)
1407 cmd
.Enable(m_View
->HasData());
1408 cmd
.Check(m_View
->DisplayingBoundingBox());
1411 void GUIControl::OnViewBoundingBox()
1413 m_View
->ToggleBoundingBox();
1416 void GUIControl::OnViewTerrainUpdate(wxUpdateUIEvent
& cmd
)
1418 cmd
.Enable(m_View
->HasTerrain());
1419 cmd
.Check(m_View
->DisplayingTerrain());
1422 void GUIControl::OnViewTerrain()
1424 m_View
->ToggleTerrain();