source: git/src/guicontrol.cc @ 76cf7f1

RELEASE/1.2debug-cidebug-ci-sanitiserswalls-datawalls-data-hanging-as-warning
Last change on this file since 76cf7f1 was fc43dda, checked in by Olly Betts <olly@…>, 5 years ago

Allow colouring by horizontal or vertical error

  • Property mode set to 100644
File size: 33.1 KB
RevLine 
[56da40e]1//
2//  guicontrol.cc
3//
4//  Handlers for events relating to the display of a survey.
5//
[f4c5932]6//  Copyright (C) 2000-2002,2005 Mark R. Shinwell
[de8e9cf]7//  Copyright (C) 2001,2003,2004,2005,2006,2011,2012,2014,2015,2016 Olly Betts
[56da40e]8//
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.
13//
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.
18//
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
[ecbc6c18]21//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
[56da40e]22//
23
[cbfa50d]24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
[56da40e]28#include "guicontrol.h"
29#include "gfxcore.h"
30#include <wx/confbase.h>
31
[0c7bb77]32const int DISPLAY_SHIFT = 10;
[d6a5001]33const double FLYFREE_SHIFT = 0.2;
[e577f89]34const double ROTATE_STEP = 2.0;
[56da40e]35
36GUIControl::GUIControl()
[82c85aa]37    : dragging(NO_DRAG)
[56da40e]38{
39    m_View = NULL;
40    m_ReverseControls = false;
41    m_LastDrag = drag_NONE;
42}
43
44void GUIControl::SetView(GfxCore* view)
45{
46    m_View = view;
47}
48
[e2c1671]49bool GUIControl::MouseDown() const
[56da40e]50{
[82c85aa]51    return (dragging != NO_DRAG);
[56da40e]52}
53
54void GUIControl::HandleTilt(wxPoint point)
55{
56    // Handle a mouse movement during tilt mode.
[e2c1671]57
58    // wxGTK (at least) fails to update the cursor while dragging.
[242cb07]59    m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
[e2c1671]60
[56da40e]61    int dy = point.y - m_DragStart.y;
62
[d877aa2]63    if (m_ReverseControls != m_View->GetPerspective()) dy = -dy;
[56da40e]64
[7a57dc7]65    m_View->TiltCave(Double(dy) * 0.36);
[56da40e]66
67    m_DragStart = point;
68
69    m_View->ForceRefresh();
70}
71
72void GUIControl::HandleTranslate(wxPoint point)
73{
74    // Handle a mouse movement during translation mode.
[e2c1671]75
76    // wxGTK (at least) fails to update the cursor while dragging.
[242cb07]77    m_View->UpdateCursor(GfxCore::CURSOR_DRAGGING_HAND);
[e2c1671]78
[56da40e]79    int dx = point.x - m_DragStart.x;
80    int dy = point.y - m_DragStart.y;
[096e56c]81
[56da40e]82    if (m_ReverseControls) {
83        dx = -dx;
84        dy = -dy;
85    }
86
[d877aa2]87    if (m_View->GetPerspective())
88        m_View->MoveViewer(0, -dy * .1, dx * .1);
89    else
90        m_View->TranslateCave(dx, dy);
91
[56da40e]92    m_DragStart = point;
93}
94
[ecf2d23]95void GUIControl::HandleScaleRotate(wxPoint point)
[dde4fe7]96{
[ecf2d23]97    // Handle a mouse movement during scale/rotate mode.
[dde4fe7]98
[e2c1671]99    // wxGTK (at least) fails to update the cursor while dragging.
[242cb07]100    m_View->UpdateCursor(GfxCore::CURSOR_ZOOM_ROTATE);
[ecf2d23]101
102    int dx, dy;
103    int threshold;
[f3ef5d8]104    if (m_ScaleRotateLock == lock_NONE) {
[ecf2d23]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;
108        threshold = 8 * 8;
109    } else {
110        dx = point.x - m_DragStart.x;
111        dy = point.y - m_DragStart.y;
112        threshold = 5;
113    }
114    int dx2 = dx * dx;
115    int dy2 = dy * dy;
116    if (dx2 + dy2 < threshold) return;
117
118    switch (m_ScaleRotateLock) {
[f3ef5d8]119        case lock_NONE:
[ecf2d23]120            if (dx2 > dy2) {
[f3ef5d8]121                m_ScaleRotateLock = lock_ROTATE;
[242cb07]122//              m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
[ecf2d23]123            } else {
[f3ef5d8]124                m_ScaleRotateLock = lock_SCALE;
[242cb07]125//              m_View->UpdateCursor(GfxCore::CURSOR_ZOOM);
[ecf2d23]126            }
127            break;
[f3ef5d8]128        case lock_SCALE:
[ecf2d23]129            if (dx2 >= 8 * dy2) {
[f3ef5d8]130                m_ScaleRotateLock = lock_ROTATE;
[242cb07]131//              m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
[ecf2d23]132            }
133            break;
[f3ef5d8]134        case lock_ROTATE:
[ecf2d23]135            if (dy2 >= 8 * dx2) {
[f3ef5d8]136                m_ScaleRotateLock = lock_SCALE;
[242cb07]137//              m_View->UpdateCursor(GfxCore::CURSOR_ZOOM);
[ecf2d23]138            }
139            break;
140    }
[e2c1671]141
[f3ef5d8]142    if (m_ScaleRotateLock == lock_ROTATE) {
[ecf2d23]143        dy = 0;
144    } else {
145        dx = 0;
146    }
[dde4fe7]147
148    if (m_ReverseControls) {
[ecf2d23]149        dx = -dx;
[dde4fe7]150        dy = -dy;
151    }
152
[d877aa2]153    if (m_View->GetPerspective()) {
[ecf2d23]154        if (dy) m_View->MoveViewer(-dy * .1, 0, 0);
[d877aa2]155    } else {
[ecf2d23]156        // up/down => scale.
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();
[d877aa2]161    }
[dde4fe7]162
163    m_DragStart = point;
164}
165
166void GUIControl::HandleTiltRotate(wxPoint point)
167{
168    // Handle a mouse movement during tilt/rotate mode.
[eef68f9]169    if (m_View->IsExtendedElevation()) return;
[dde4fe7]170
[e2c1671]171    // wxGTK (at least) fails to update the cursor while dragging.
[242cb07]172    m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY);
[e2c1671]173
[dde4fe7]174    int dx = point.x - m_DragStart.x;
175    int dy = point.y - m_DragStart.y;
176
[d877aa2]177    if (m_ReverseControls != m_View->GetPerspective()) {
[dde4fe7]178        dx = -dx;
179        dy = -dy;
180    }
181
[e577f89]182    // left/right => rotate, up/down => tilt.
183    // Make tilt less sensitive than rotate as that feels better.
[eef68f9]184    m_View->TurnCave(Double(dx) * -0.36);
[7a57dc7]185    m_View->TiltCave(Double(dy) * 0.18);
[dde4fe7]186
187    m_View->ForceRefresh();
188
189    m_DragStart = point;
190}
191
[e2c1671]192void GUIControl::HandleRotate(wxPoint point)
[56da40e]193{
[e2c1671]194    // Handle a mouse movement during rotate mode.
[eef68f9]195    if (m_View->IsExtendedElevation()) return;
[e2c1671]196
197    // wxGTK (at least) fails to update the cursor while dragging.
[242cb07]198    m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
[e2c1671]199
[56da40e]200    int dx = point.x - m_DragStart.x;
201    int dy = point.y - m_DragStart.y;
202
[e2c1671]203    if (m_ReverseControls != m_View->GetPerspective()) {
[56da40e]204        dx = -dx;
205        dy = -dy;
206    }
207
[e2c1671]208    // left/right => rotate.
[eef68f9]209    m_View->TurnCave(Double(dx) * -0.36);
[56da40e]210
211    m_View->ForceRefresh();
212
213    m_DragStart = point;
214}
215
[203d2a7]216void GUIControl::RestoreCursor()
217{
[570d62c3]218    if (m_View->HereIsReal()) {
[242cb07]219        m_View->UpdateCursor(GfxCore::CURSOR_POINTING_HAND);
[096e56c]220    } else {
[242cb07]221        m_View->UpdateCursor(GfxCore::CURSOR_DEFAULT);
[203d2a7]222    }
223}
224
[2072157]225void GUIControl::HandleNonDrag(const wxPoint & point) {
[b75a37d]226    if (m_View->IsFullScreen()) {
227        if (m_View->FullScreenModeShowingMenus()) {
228            if (point.y > 8)
229                m_View->FullScreenModeShowMenus(false);
230        } else {
231            if (point.y == 0) {
232                m_View->FullScreenModeShowMenus(true);
233            }
234        }
235    }
[2072157]236    if (m_View->CheckHitTestGrid(point, false)) {
[242cb07]237        m_View->UpdateCursor(GfxCore::CURSOR_POINTING_HAND);
[2072157]238    } else if (m_View->PointWithinScaleBar(point)) {
[242cb07]239        m_View->UpdateCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE);
[2072157]240    } else if (m_View->PointWithinCompass(point)) {
[242cb07]241        m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
[2072157]242    } else if (m_View->PointWithinClino(point)) {
[242cb07]243        m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
[2072157]244    } else {
245        RestoreCursor();
246    }
247}
248
[56da40e]249//
250//  Mouse event handling methods
251//
252
253void GUIControl::OnMouseMove(wxMouseEvent& event)
254{
255    // Mouse motion event handler.
256    if (!m_View->HasData()) return;
257
[ecf2d23]258    // Ignore moves which don't change the position.
[2072157]259    if (event.GetPosition() == m_DragStart) {
[ecf2d23]260        return;
261    }
262
263    static long timestamp = LONG_MIN;
[f3ef5d8]264    if (dragging != NO_DRAG && m_ScaleRotateLock != lock_NONE &&
265        timestamp != LONG_MIN) {
[ecf2d23]266        // If no motion for a second, reset the direction lock.
267        if (event.GetTimestamp() - timestamp >= 1000) {
[f3ef5d8]268            m_ScaleRotateLock = lock_NONE;
[ecf2d23]269            m_DragRealStart = m_DragStart;
270            RestoreCursor();
271        }
272    }
273    timestamp = event.GetTimestamp();
274
[2072157]275    wxPoint point(event.GetPosition());
[56da40e]276
277    // Check hit-test grid (only if no buttons are pressed).
278    if (!event.LeftIsDown() && !event.MiddleIsDown() && !event.RightIsDown()) {
[2072157]279        HandleNonDrag(point);
[56da40e]280    }
281
[203d2a7]282    // Update coordinate display if in plan view,
283    // or altitude if in elevation view.
[56da40e]284    m_View->SetCoords(point);
285
[2a3d328]286    switch (dragging) {
287        case LEFT_DRAG:
[e2c1671]288            switch (m_LastDrag) {
289                case drag_COMPASS:
290                    // Drag in heading indicator.
291                    m_View->SetCompassFromPoint(point);
292                    break;
293                case drag_ELEV:
294                    // Drag in clinometer.
295                    m_View->SetClinoFromPoint(point);
296                    break;
297                case drag_SCALE:
298                    m_View->SetScaleBarFromOffset(point.x - m_DragLast.x);
299                    break;
300                case drag_MAIN:
301                    if (event.ControlDown()) {
302                        HandleTiltRotate(point);
303                    } else {
[ecf2d23]304                        HandleScaleRotate(point);
[e2c1671]305                    }
306                    break;
[dd6af8b]307                case drag_ZOOM:
308                    m_View->SetZoomBox(m_DragStart, point, !event.ShiftDown(), event.ControlDown());
309                    break;
[e2c1671]310                case drag_NONE:
311                    // Shouldn't happen?!  FIXME: assert or something.
312                    break;
[2a3d328]313            }
314            break;
315        case MIDDLE_DRAG:
[ecf2d23]316            HandleTilt(point);
[2a3d328]317            break;
318        case RIGHT_DRAG:
[e2c1671]319            HandleTranslate(point);
[2a3d328]320            break;
321        case NO_DRAG:
322            break;
[56da40e]323    }
324
325    m_DragLast = point;
326}
327
328void GUIControl::OnLButtonDown(wxMouseEvent& event)
329{
[eef68f9]330    if (m_View->HasData()) {
[2072157]331        m_DragStart = m_DragRealStart = event.GetPosition();
[096e56c]332
[e2c1671]333        if (m_View->PointWithinCompass(m_DragStart)) {
334            m_LastDrag = drag_COMPASS;
[242cb07]335            m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
[e2c1671]336        } else if (m_View->PointWithinClino(m_DragStart)) {
337            m_LastDrag = drag_ELEV;
[242cb07]338            m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
[e2c1671]339        } else if (m_View->PointWithinScaleBar(m_DragStart)) {
340            m_LastDrag = drag_SCALE;
[242cb07]341            m_View->UpdateCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE);
[dd6af8b]342        } else if (event.ShiftDown()) {
343            m_LastDrag = drag_ZOOM;
[242cb07]344            m_View->UpdateCursor(GfxCore::CURSOR_ZOOM);
[e2c1671]345        } else {
[e0f3ade]346            if (event.ControlDown() && !m_View->IsExtendedElevation()) {
[242cb07]347                m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY);
[e2c1671]348            } else {
[242cb07]349                m_View->UpdateCursor(GfxCore::CURSOR_ZOOM_ROTATE);
[e2c1671]350            }
[7c29c976]351
352            m_LastDrag = drag_MAIN;
[f3ef5d8]353            m_ScaleRotateLock = lock_NONE;
[e2c1671]354        }
355
[a57af18]356        // We need to release and recapture for the cursor to update (noticed
357        // with wxGTK).
358        if (dragging != NO_DRAG) m_View->ReleaseMouse();
[56da40e]359        m_View->CaptureMouse();
[a57af18]360
361        dragging = LEFT_DRAG;
[56da40e]362    }
363}
364
365void GUIControl::OnLButtonUp(wxMouseEvent& event)
366{
[eef68f9]367    if (m_View->HasData()) {
[a57af18]368        if (dragging != LEFT_DRAG)
[76882cb]369            return;
370
[e0f3ade]371        if (event.MiddleIsDown()) {
[dd6af8b]372            if (m_LastDrag == drag_ZOOM)
373                m_View->UnsetZoomBox();
[e0f3ade]374            OnMButtonDown(event);
375            return;
376        }
377
378        if (event.RightIsDown()) {
[dd6af8b]379            if (m_LastDrag == drag_ZOOM)
380                m_View->UnsetZoomBox();
[e0f3ade]381            OnRButtonDown(event);
382            return;
383        }
384
[dd6af8b]385        if (m_LastDrag == drag_ZOOM) {
386            m_View->ZoomBoxGo();
387        }
388
[56da40e]389        m_View->ReleaseMouse();
390
391        m_LastDrag = drag_NONE;
[82c85aa]392        dragging = NO_DRAG;
[56da40e]393
[a57af18]394        m_View->DragFinished();
[096e56c]395
[2072157]396        if (event.GetPosition() == m_DragRealStart) {
[655aa2c]397            // Just a "click"...
398            m_View->CheckHitTestGrid(m_DragStart, true);
[2072157]399            RestoreCursor();
400        } else {
401            HandleNonDrag(event.GetPosition());
402        }
[56da40e]403    }
404}
405
406void GUIControl::OnMButtonDown(wxMouseEvent& event)
407{
[eef68f9]408    if (m_View->HasData() && !m_View->IsExtendedElevation()) {
[2072157]409        m_DragStart = event.GetPosition();
[56da40e]410
[242cb07]411        m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
[e2c1671]412
[dd6af8b]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();
419        }
[56da40e]420        m_View->CaptureMouse();
[a57af18]421        dragging = MIDDLE_DRAG;
[56da40e]422    }
423}
424
[e0f3ade]425void GUIControl::OnMButtonUp(wxMouseEvent& event)
[56da40e]426{
[eef68f9]427    if (m_View->HasData()) {
[a57af18]428        if (dragging != MIDDLE_DRAG)
429            return;
430
[e0f3ade]431        if (event.LeftIsDown()) {
432            OnLButtonDown(event);
433            return;
434        }
435
436        if (event.RightIsDown()) {
437            OnRButtonDown(event);
438            return;
439        }
440
[82c85aa]441        dragging = NO_DRAG;
[56da40e]442        m_View->ReleaseMouse();
[a57af18]443        m_View->DragFinished();
[203d2a7]444
[a57af18]445        RestoreCursor();
[56da40e]446    }
447}
448
449void GUIControl::OnRButtonDown(wxMouseEvent& event)
450{
451    if (m_View->HasData()) {
[acdb8aa]452        if (m_View->HandleRClick(event.GetPosition()))
453            return;
454
[2072157]455        m_DragStart = event.GetPosition();
[096e56c]456
[242cb07]457        m_View->UpdateCursor(GfxCore::CURSOR_DRAGGING_HAND);
[56da40e]458
[dd6af8b]459        if (dragging != NO_DRAG) {
460            if (m_LastDrag == drag_ZOOM)
461                m_View->UnsetZoomBox();
462            // We need to release and recapture for the cursor to update
463            // (noticed with wxGTK).
464            m_View->ReleaseMouse();
465        }
[56da40e]466        m_View->CaptureMouse();
[a57af18]467        dragging = RIGHT_DRAG;
[56da40e]468    }
469}
470
[e0f3ade]471void GUIControl::OnRButtonUp(wxMouseEvent& event)
[56da40e]472{
[a57af18]473    if (dragging != RIGHT_DRAG)
474        return;
475
[e0f3ade]476    if (event.LeftIsDown()) {
477        OnLButtonDown(event);
478        return;
479    }
480
481    if (event.MiddleIsDown()) {
482        OnMButtonDown(event);
483        return;
484    }
485
[56da40e]486    m_LastDrag = drag_NONE;
487    m_View->ReleaseMouse();
488
[82c85aa]489    dragging = NO_DRAG;
[096e56c]490
[203d2a7]491    RestoreCursor();
[096e56c]492
[56da40e]493    m_View->DragFinished();
494}
495
[34d8d1a]496void GUIControl::OnMouseWheel(wxMouseEvent& event) {
[ecf2d23]497    int dy = event.GetWheelRotation();
498    if (m_View->GetPerspective()) {
499        m_View->MoveViewer(-dy, 0, 0);
500    } else {
501        m_View->SetScale(m_View->GetScale() * pow(1.06, -0.04 * dy));
[7c29c976]502        m_View->ForceRefresh();
503    }
[34d8d1a]504}
505
[56da40e]506void GUIControl::OnDisplayOverlappingNames()
507{
508    m_View->ToggleOverlappingNames();
509}
510
511void GUIControl::OnDisplayOverlappingNamesUpdate(wxUpdateUIEvent& cmd)
512{
513    cmd.Enable(m_View->HasData() && m_View->ShowingStationNames());
514    cmd.Check(m_View->ShowingOverlappingNames());
515}
516
[da6c802]517void GUIControl::OnColourByDepth()
518{
519    if (m_View->ColouringBy() == COLOUR_BY_DEPTH) {
520        m_View->SetColourBy(COLOUR_BY_NONE);
521    } else {
522        m_View->SetColourBy(COLOUR_BY_DEPTH);
523    }
524}
525
[d4650b3]526void GUIControl::OnColourByDate()
527{
528    if (m_View->ColouringBy() == COLOUR_BY_DATE) {
529        m_View->SetColourBy(COLOUR_BY_NONE);
530    } else {
531        m_View->SetColourBy(COLOUR_BY_DATE);
532    }
533}
534
[c61aa79]535void GUIControl::OnColourByError()
536{
537    if (m_View->ColouringBy() == COLOUR_BY_ERROR) {
538        m_View->SetColourBy(COLOUR_BY_NONE);
539    } else {
540        m_View->SetColourBy(COLOUR_BY_ERROR);
541    }
542}
543
[fc43dda]544void GUIControl::OnColourByHError()
545{
546    if (m_View->ColouringBy() == COLOUR_BY_H_ERROR) {
547        m_View->SetColourBy(COLOUR_BY_NONE);
548    } else {
549        m_View->SetColourBy(COLOUR_BY_H_ERROR);
550    }
551}
552
553void GUIControl::OnColourByVError()
554{
555    if (m_View->ColouringBy() == COLOUR_BY_V_ERROR) {
556        m_View->SetColourBy(COLOUR_BY_NONE);
557    } else {
558        m_View->SetColourBy(COLOUR_BY_V_ERROR);
559    }
560}
561
[cc9e2c65]562void GUIControl::OnColourByGradient()
563{
564    if (m_View->ColouringBy() == COLOUR_BY_GRADIENT) {
565        m_View->SetColourBy(COLOUR_BY_NONE);
566    } else {
567        m_View->SetColourBy(COLOUR_BY_GRADIENT);
568    }
569}
570
[af50685]571void GUIControl::OnColourByLength()
572{
573    if (m_View->ColouringBy() == COLOUR_BY_LENGTH) {
574        m_View->SetColourBy(COLOUR_BY_NONE);
575    } else {
576        m_View->SetColourBy(COLOUR_BY_LENGTH);
577    }
578}
579
[68fb07a]580void GUIControl::OnColourBySurvey()
581{
582    if (m_View->ColouringBy() == COLOUR_BY_SURVEY) {
583        m_View->SetColourBy(COLOUR_BY_NONE);
584    } else {
585        m_View->SetColourBy(COLOUR_BY_SURVEY);
586    }
587}
588
[46beda0]589void GUIControl::OnColourByUpdate(wxUpdateUIEvent& cmd)
590{
591    cmd.Enable(m_View->HasData());
592}
593
[da6c802]594void GUIControl::OnColourByDepthUpdate(wxUpdateUIEvent& cmd)
595{
[ff5db1d5]596    cmd.Enable(m_View->HasData());
[da6c802]597    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DEPTH);
598}
599
[d4650b3]600void GUIControl::OnColourByDateUpdate(wxUpdateUIEvent& cmd)
601{
[ff5db1d5]602    cmd.Enable(m_View->HasData());
[d4650b3]603    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DATE);
604}
605
[c61aa79]606void GUIControl::OnColourByErrorUpdate(wxUpdateUIEvent& cmd)
607{
[ff5db1d5]608    cmd.Enable(m_View->HasData());
[c61aa79]609    cmd.Check(m_View->ColouringBy() == COLOUR_BY_ERROR);
610}
611
[fc43dda]612void GUIControl::OnColourByHErrorUpdate(wxUpdateUIEvent& cmd)
613{
614    cmd.Enable(m_View->HasData());
615    cmd.Check(m_View->ColouringBy() == COLOUR_BY_H_ERROR);
616}
617
618void GUIControl::OnColourByVErrorUpdate(wxUpdateUIEvent& cmd)
619{
620    cmd.Enable(m_View->HasData());
621    cmd.Check(m_View->ColouringBy() == COLOUR_BY_V_ERROR);
622}
623
[cc9e2c65]624void GUIControl::OnColourByGradientUpdate(wxUpdateUIEvent& cmd)
625{
626    cmd.Enable(m_View->HasData());
627    cmd.Check(m_View->ColouringBy() == COLOUR_BY_GRADIENT);
628}
629
[af50685]630void GUIControl::OnColourByLengthUpdate(wxUpdateUIEvent& cmd)
631{
632    cmd.Enable(m_View->HasData());
633    cmd.Check(m_View->ColouringBy() == COLOUR_BY_LENGTH);
634}
635
[68fb07a]636void GUIControl::OnColourBySurveyUpdate(wxUpdateUIEvent& cmd)
637{
638    cmd.Enable(m_View->HasData());
639    cmd.Check(m_View->ColouringBy() == COLOUR_BY_SURVEY);
640}
641
[56da40e]642void GUIControl::OnShowCrosses()
643{
644    m_View->ToggleCrosses();
645}
646
647void GUIControl::OnShowCrossesUpdate(wxUpdateUIEvent& cmd)
648{
649    cmd.Enable(m_View->HasData());
650    cmd.Check(m_View->ShowingCrosses());
651}
652
653void GUIControl::OnShowStationNames()
654{
655    m_View->ToggleStationNames();
656}
657
658void GUIControl::OnShowStationNamesUpdate(wxUpdateUIEvent& cmd)
659{
660    cmd.Enable(m_View->HasData());
661    cmd.Check(m_View->ShowingStationNames());
662}
663
664void GUIControl::OnShowSurveyLegs()
665{
666    m_View->ToggleUndergroundLegs();
667}
668
669void GUIControl::OnShowSurveyLegsUpdate(wxUpdateUIEvent& cmd)
670{
[eef68f9]671    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs());
[56da40e]672    cmd.Check(m_View->ShowingUndergroundLegs());
673}
674
[8666fc7]675void GUIControl::OnHideSplays()
[5fe7292]676{
[cca3cee]677    m_View->SetSplaysMode(SHOW_HIDE);
[8666fc7]678}
679
[b96edeb]680void GUIControl::OnShowSplaysDashed()
[8666fc7]681{
[b96edeb]682    m_View->SetSplaysMode(SHOW_DASHED);
[8666fc7]683}
684
685void GUIControl::OnShowSplaysFaded()
686{
[cca3cee]687    m_View->SetSplaysMode(SHOW_FADED);
[5fe7292]688}
689
[b96edeb]690void GUIControl::OnShowSplaysNormal()
691{
692    m_View->SetSplaysMode(SHOW_NORMAL);
693}
694
[9cb97b7]695void GUIControl::OnSplaysUpdate(wxUpdateUIEvent& cmd)
[5fe7292]696{
697    cmd.Enable(m_View->HasData() && m_View->HasSplays());
[8666fc7]698}
699
700void GUIControl::OnHideSplaysUpdate(wxUpdateUIEvent& cmd)
701{
702    cmd.Enable(m_View->HasData() && m_View->HasSplays());
[cca3cee]703    cmd.Check(m_View->ShowingSplaysMode() == SHOW_HIDE);
[8666fc7]704}
705
[b96edeb]706void GUIControl::OnShowSplaysDashedUpdate(wxUpdateUIEvent& cmd)
[8666fc7]707{
708    cmd.Enable(m_View->HasData() && m_View->HasSplays());
[b96edeb]709    cmd.Check(m_View->ShowingSplaysMode() == SHOW_DASHED);
[8666fc7]710}
711
712void GUIControl::OnShowSplaysFadedUpdate(wxUpdateUIEvent& cmd)
713{
714    cmd.Enable(m_View->HasData() && m_View->HasSplays());
[cca3cee]715    cmd.Check(m_View->ShowingSplaysMode() == SHOW_FADED);
[5fe7292]716}
717
[b96edeb]718void GUIControl::OnShowSplaysNormalUpdate(wxUpdateUIEvent& cmd)
719{
720    cmd.Enable(m_View->HasData() && m_View->HasSplays());
721    cmd.Check(m_View->ShowingSplaysMode() == SHOW_NORMAL);
[e5c5f3c]722}
723
[b96edeb]724void GUIControl::OnHideDupes() {
725    m_View->SetDupesMode(SHOW_HIDE);
[e5c5f3c]726}
727
728void GUIControl::OnShowDupesDashed() {
[cca3cee]729    m_View->SetDupesMode(SHOW_DASHED);
[e5c5f3c]730}
731
[b96edeb]732void GUIControl::OnShowDupesFaded() {
733    m_View->SetDupesMode(SHOW_FADED);
734}
735
736void GUIControl::OnShowDupesNormal() {
737    m_View->SetDupesMode(SHOW_NORMAL);
738}
739
[e5c5f3c]740void GUIControl::OnDupesUpdate(wxUpdateUIEvent& cmd) {
741    cmd.Enable(m_View->HasData() && m_View->HasDupes());
742}
743
744void GUIControl::OnHideDupesUpdate(wxUpdateUIEvent& cmd) {
745    cmd.Enable(m_View->HasData() && m_View->HasDupes());
[cca3cee]746    cmd.Check(m_View->ShowingDupesMode() == SHOW_HIDE);
[e5c5f3c]747}
748
[b96edeb]749void GUIControl::OnShowDupesDashedUpdate(wxUpdateUIEvent& cmd) {
[e5c5f3c]750    cmd.Enable(m_View->HasData() && m_View->HasDupes());
[b96edeb]751    cmd.Check(m_View->ShowingDupesMode() == SHOW_DASHED);
[e5c5f3c]752}
753
[b96edeb]754void GUIControl::OnShowDupesFadedUpdate(wxUpdateUIEvent& cmd) {
[e5c5f3c]755    cmd.Enable(m_View->HasData() && m_View->HasDupes());
[b96edeb]756    cmd.Check(m_View->ShowingDupesMode() == SHOW_FADED);
757}
758
759void GUIControl::OnShowDupesNormalUpdate(wxUpdateUIEvent& cmd) {
760    cmd.Enable(m_View->HasData() && m_View->HasDupes());
761    cmd.Check(m_View->ShowingDupesMode() == SHOW_NORMAL);
[e5c5f3c]762}
763
[56da40e]764void GUIControl::OnMoveEast()
765{
[e577f89]766    m_View->TurnCaveTo(90.0);
[56da40e]767    m_View->ForceRefresh();
768}
769
770void GUIControl::OnMoveEastUpdate(wxUpdateUIEvent& cmd)
771{
[11c594a]772    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 90.0);
[56da40e]773}
774
775void GUIControl::OnMoveNorth()
776{
777    m_View->TurnCaveTo(0.0);
778    m_View->ForceRefresh();
779}
780
781void GUIControl::OnMoveNorthUpdate(wxUpdateUIEvent& cmd)
782{
[11c594a]783    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 0.0);
[56da40e]784}
785
786void GUIControl::OnMoveSouth()
787{
[e577f89]788    m_View->TurnCaveTo(180.0);
[56da40e]789    m_View->ForceRefresh();
790}
791
792void GUIControl::OnMoveSouthUpdate(wxUpdateUIEvent& cmd)
793{
[11c594a]794    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 180.0);
[56da40e]795}
796
797void GUIControl::OnMoveWest()
798{
[e577f89]799    m_View->TurnCaveTo(270.0);
[56da40e]800    m_View->ForceRefresh();
801}
802
803void GUIControl::OnMoveWestUpdate(wxUpdateUIEvent& cmd)
804{
[11c594a]805    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 270.0);
[56da40e]806}
807
808void GUIControl::OnToggleRotation()
809{
810    m_View->ToggleRotation();
811}
812
813void GUIControl::OnToggleRotationUpdate(wxUpdateUIEvent& cmd)
814{
[eef68f9]815    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
[56da40e]816    cmd.Check(m_View->HasData() && m_View->IsRotating());
817}
818
819void GUIControl::OnReverseControls()
820{
821    m_ReverseControls = !m_ReverseControls;
822}
823
824void GUIControl::OnReverseControlsUpdate(wxUpdateUIEvent& cmd)
825{
826    cmd.Enable(m_View->HasData());
827    cmd.Check(m_ReverseControls);
828}
829
830void GUIControl::OnReverseDirectionOfRotation()
831{
832    m_View->ReverseRotation();
833}
834
835void GUIControl::OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent& cmd)
836{
[eef68f9]837    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
[56da40e]838}
839
840void GUIControl::OnStepOnceAnticlockwise(bool accel)
841{
[d877aa2]842    if (m_View->GetPerspective()) {
843        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
844    } else {
845        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
846    }
[56da40e]847    m_View->ForceRefresh();
848}
849
850void GUIControl::OnStepOnceClockwise(bool accel)
851{
[d877aa2]852    if (m_View->GetPerspective()) {
853        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
854    } else {
855        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
856    }
[56da40e]857    m_View->ForceRefresh();
858}
859
860void GUIControl::OnDefaults()
861{
862    m_View->Defaults();
863}
864
865void GUIControl::OnDefaultsUpdate(wxUpdateUIEvent& cmd)
866{
867    cmd.Enable(m_View->HasData());
868}
869
870void GUIControl::OnElevation()
871{
872    // Switch to elevation view.
873
874    m_View->SwitchToElevation();
875}
876
877void GUIControl::OnElevationUpdate(wxUpdateUIEvent& cmd)
878{
[eef68f9]879    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingElevation());
[56da40e]880}
881
882void GUIControl::OnHigherViewpoint(bool accel)
883{
884    // Raise the viewpoint.
[d877aa2]885    if (m_View->GetPerspective()) {
886        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
[7a57dc7]887    } else {
888        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
[d877aa2]889    }
[56da40e]890    m_View->ForceRefresh();
891}
892
893void GUIControl::OnLowerViewpoint(bool accel)
894{
895    // Lower the viewpoint.
[d877aa2]896    if (m_View->GetPerspective()) {
897        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
[7a57dc7]898    } else {
899        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
[d877aa2]900    }
[d6a5001]901    m_View->ForceRefresh();
[56da40e]902}
903
904void GUIControl::OnPlan()
905{
906    // Switch to plan view.
907    m_View->SwitchToPlan();
908}
909
910void GUIControl::OnPlanUpdate(wxUpdateUIEvent& cmd)
911{
[eef68f9]912    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingPlan());
[56da40e]913}
914
915void GUIControl::OnShiftDisplayDown(bool accel)
916{
[096e56c]917    if (m_View->GetPerspective())
[867a1141]918        m_View->MoveViewer(0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0);
[d877aa2]919    else
920        m_View->TranslateCave(0, accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT);
[56da40e]921}
922
923void GUIControl::OnShiftDisplayLeft(bool accel)
924{
[096e56c]925    if (m_View->GetPerspective())
[867a1141]926        m_View->MoveViewer(0, 0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT);
[d877aa2]927    else
928        m_View->TranslateCave(accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT, 0);
[56da40e]929}
930
931void GUIControl::OnShiftDisplayRight(bool accel)
932{
[096e56c]933    if (m_View->GetPerspective())
[867a1141]934        m_View->MoveViewer(0, 0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT);
[d877aa2]935    else
936        m_View->TranslateCave(accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT, 0);
[56da40e]937}
938
939void GUIControl::OnShiftDisplayUp(bool accel)
940{
[096e56c]941    if (m_View->GetPerspective())
[867a1141]942        m_View->MoveViewer(0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0);
[d877aa2]943    else
944        m_View->TranslateCave(0, accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT);
[56da40e]945}
946
947void GUIControl::OnZoomIn(bool accel)
948{
949    // Increase the scale.
950
[d877aa2]951    if (m_View->GetPerspective()) {
952        m_View->MoveViewer(accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0, 0);
953    } else {
954        m_View->SetScale(m_View->GetScale() * (accel ? 1.1236 : 1.06));
955        m_View->ForceRefresh();
956    }
[56da40e]957}
958
959void GUIControl::OnZoomOut(bool accel)
960{
961    // Decrease the scale.
962
[d877aa2]963    if (m_View->GetPerspective()) {
964        m_View->MoveViewer(accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0, 0);
965    } else {
966        m_View->SetScale(m_View->GetScale() / (accel ? 1.1236 : 1.06));
967        m_View->ForceRefresh();
968    }
[56da40e]969}
970
971void GUIControl::OnToggleScalebar()
972{
973    m_View->ToggleScaleBar();
974}
975
976void GUIControl::OnToggleScalebarUpdate(wxUpdateUIEvent& cmd)
977{
[eef68f9]978    cmd.Enable(m_View->HasData());
[56da40e]979    cmd.Check(m_View->ShowingScaleBar());
980}
981
[97ea48d]982void GUIControl::OnToggleColourKey()
[56da40e]983{
[97ea48d]984    m_View->ToggleColourKey();
[56da40e]985}
986
[97ea48d]987void GUIControl::OnToggleColourKeyUpdate(wxUpdateUIEvent& cmd)
[56da40e]988{
[97ea48d]989    cmd.Enable(m_View->HasData() && m_View->ColouringBy() != COLOUR_BY_NONE);
990    cmd.Check(m_View->ShowingColourKey());
[56da40e]991}
992
993void GUIControl::OnViewCompass()
994{
995    m_View->ToggleCompass();
996}
997
998void GUIControl::OnViewCompassUpdate(wxUpdateUIEvent& cmd)
999{
[eef68f9]1000    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
[56da40e]1001    cmd.Check(m_View->ShowingCompass());
1002}
1003
1004void GUIControl::OnViewClino()
1005{
1006    m_View->ToggleClino();
1007}
1008
1009void GUIControl::OnViewClinoUpdate(wxUpdateUIEvent& cmd)
1010{
[eef68f9]1011    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
[56da40e]1012    cmd.Check(m_View->ShowingClino());
1013}
1014
1015void GUIControl::OnShowSurface()
1016{
1017    m_View->ToggleSurfaceLegs();
1018}
1019
1020void GUIControl::OnShowSurfaceUpdate(wxUpdateUIEvent& cmd)
1021{
1022    cmd.Enable(m_View->HasData() && m_View->HasSurfaceLegs());
1023    cmd.Check(m_View->ShowingSurfaceLegs());
1024}
1025
1026void GUIControl::OnShowEntrances()
1027{
1028    m_View->ToggleEntrances();
1029}
1030
1031void GUIControl::OnShowEntrancesUpdate(wxUpdateUIEvent& cmd)
1032{
1033    cmd.Enable(m_View->HasData() && (m_View->GetNumEntrances() > 0));
1034    cmd.Check(m_View->ShowingEntrances());
1035}
1036
1037void GUIControl::OnShowFixedPts()
1038{
1039    m_View->ToggleFixedPts();
1040}
1041
1042void GUIControl::OnShowFixedPtsUpdate(wxUpdateUIEvent& cmd)
1043{
1044    cmd.Enable(m_View->HasData() && (m_View->GetNumFixedPts() > 0));
1045    cmd.Check(m_View->ShowingFixedPts());
1046}
1047
1048void GUIControl::OnShowExportedPts()
1049{
1050    m_View->ToggleExportedPts();
1051}
1052
1053void GUIControl::OnShowExportedPtsUpdate(wxUpdateUIEvent& cmd)
1054{
[cd39f67]1055    cmd.Enable(m_View->HasData() && (m_View->GetNumExportedPts() > 0));
[56da40e]1056    cmd.Check(m_View->ShowingExportedPts());
1057}
1058
1059void GUIControl::OnViewGrid()
1060{
1061    m_View->ToggleGrid();
1062}
1063
1064void GUIControl::OnViewGridUpdate(wxUpdateUIEvent& cmd)
1065{
1066    cmd.Enable(m_View->HasData());
[0580c6a]1067    cmd.Check(m_View->ShowingGrid());
[56da40e]1068}
1069
1070void GUIControl::OnIndicatorsUpdate(wxUpdateUIEvent& cmd)
1071{
1072    cmd.Enable(m_View->HasData());
1073}
1074
[6abab84]1075void GUIControl::OnViewPerspective()
1076{
1077    m_View->TogglePerspective();
[d877aa2]1078    // Force update of coordinate display.
1079    if (m_View->GetPerspective()) {
1080        m_View->MoveViewer(0, 0, 0);
1081    } else {
1082        m_View->ClearCoords();
1083    }
[6abab84]1084}
1085
1086void GUIControl::OnViewPerspectiveUpdate(wxUpdateUIEvent& cmd)
1087{
[114c8fd]1088    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
[6abab84]1089    cmd.Check(m_View->GetPerspective());
1090}
1091
[d67450e]1092void GUIControl::OnViewSmoothShading()
1093{
1094    m_View->ToggleSmoothShading();
1095}
1096
1097void GUIControl::OnViewSmoothShadingUpdate(wxUpdateUIEvent& cmd)
1098{
1099    cmd.Enable(m_View->HasData());
1100    cmd.Check(m_View->GetSmoothShading());
1101}
1102
[a517825]1103void GUIControl::OnViewTextured()
1104{
1105    m_View->ToggleTextured();
1106}
1107
1108void GUIControl::OnViewTexturedUpdate(wxUpdateUIEvent& cmd)
1109{
1110    cmd.Enable(m_View->HasData());
1111    cmd.Check(m_View->GetTextured());
1112}
1113
[c60062d]1114void GUIControl::OnViewFog()
1115{
1116    m_View->ToggleFog();
1117}
1118
1119void GUIControl::OnViewFogUpdate(wxUpdateUIEvent& cmd)
1120{
1121    cmd.Enable(m_View->HasData());
1122    cmd.Check(m_View->GetFog());
1123}
1124
[db452ae]1125void GUIControl::OnViewSmoothLines()
1126{
1127    m_View->ToggleAntiAlias();
1128}
1129
1130void GUIControl::OnViewSmoothLinesUpdate(wxUpdateUIEvent& cmd)
1131{
1132    cmd.Enable(m_View->HasData());
1133    cmd.Check(m_View->GetAntiAlias());
1134}
1135
[56da40e]1136void GUIControl::OnToggleMetric()
1137{
1138    m_View->ToggleMetric();
1139
[5627cbb]1140    wxConfigBase::Get()->Write(wxT("metric"), m_View->GetMetric());
[56da40e]1141    wxConfigBase::Get()->Flush();
1142}
1143
1144void GUIControl::OnToggleMetricUpdate(wxUpdateUIEvent& cmd)
1145{
1146    cmd.Enable(m_View->HasData());
1147    cmd.Check(m_View->GetMetric());
1148}
1149
1150void GUIControl::OnToggleDegrees()
1151{
1152    m_View->ToggleDegrees();
[096e56c]1153
[5627cbb]1154    wxConfigBase::Get()->Write(wxT("degrees"), m_View->GetDegrees());
[56da40e]1155    wxConfigBase::Get()->Flush();
1156}
1157
1158void GUIControl::OnToggleDegreesUpdate(wxUpdateUIEvent& cmd)
1159{
1160    cmd.Enable(m_View->HasData());
1161    cmd.Check(m_View->GetDegrees());
1162}
1163
[d171c0c]1164void GUIControl::OnTogglePercent()
1165{
1166    m_View->TogglePercent();
1167
1168    wxConfigBase::Get()->Write(wxT("percent"), m_View->GetPercent());
1169    wxConfigBase::Get()->Flush();
1170}
1171
1172void GUIControl::OnTogglePercentUpdate(wxUpdateUIEvent& cmd)
1173{
1174    cmd.Enable(m_View->HasData());
1175    cmd.Check(m_View->GetPercent());
1176}
1177
[56da40e]1178void GUIControl::OnToggleTubes()
1179{
1180    m_View->ToggleTubes();
1181}
1182
1183void GUIControl::OnToggleTubesUpdate(wxUpdateUIEvent& cmd)
1184{
[50e8979]1185    cmd.Enable(m_View->HasData() && m_View->HasTubes());
[56da40e]1186    cmd.Check(m_View->GetTubes());
1187}
1188
1189void GUIControl::OnCancelDistLine()
1190{
1191    m_View->ClearTreeSelection();
1192}
1193
1194void GUIControl::OnCancelDistLineUpdate(wxUpdateUIEvent& cmd)
1195{
1196    cmd.Enable(m_View->ShowingMeasuringLine());
1197}
1198
1199void GUIControl::OnKeyPress(wxKeyEvent &e)
1200{
[4b1e5a4]1201    if (!m_View->HasData() ||
1202        (e.GetModifiers() &~ (wxMOD_CONTROL|wxMOD_SHIFT))) {
1203        // Pass on the event if there's no survey data, or if any modifier keys
1204        // other than Ctrl and Shift are pressed.
[56da40e]1205        e.Skip();
1206        return;
1207    }
1208
[1690fa9]1209    // The changelog says this is meant to keep animation going while keys are
1210    // pressed, but that happens anyway (on linux at least - perhaps it helps
1211    // on windows?)  FIXME : check!
1212    //bool refresh = m_View->Animate();
[56da40e]1213
[a6e8d45]1214    switch (e.GetKeyCode()) {
[56da40e]1215        case '/': case '?':
[eef68f9]1216            if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
[a6e8d45]1217                OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1218            break;
1219        case '\'': case '@': case '"': // both shifted forms - US and UK kbd
[eef68f9]1220            if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
[a6e8d45]1221                OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1222            break;
1223        case 'C': case 'c':
[eef68f9]1224            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
[a6e8d45]1225                OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1226            break;
1227        case 'V': case 'v':
[eef68f9]1228            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
[a6e8d45]1229                OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1230            break;
1231        case ']': case '}':
[a6e8d45]1232            OnZoomIn(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1233            break;
1234        case '[': case '{':
[a6e8d45]1235            OnZoomOut(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1236            break;
1237        case 'N': case 'n':
[eef68f9]1238            OnMoveNorth();
[56da40e]1239            break;
1240        case 'S': case 's':
[eef68f9]1241            OnMoveSouth();
[56da40e]1242            break;
1243        case 'E': case 'e':
[eef68f9]1244            if (!m_View->IsExtendedElevation())
[56da40e]1245                OnMoveEast();
1246            break;
1247        case 'W': case 'w':
[eef68f9]1248            if (!m_View->IsExtendedElevation())
[56da40e]1249                OnMoveWest();
1250            break;
1251        case 'Z': case 'z':
[eef68f9]1252            if (!m_View->IsExtendedElevation())
[a9a4db0]1253                m_View->RotateFaster(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1254            break;
1255        case 'X': case 'x':
[eef68f9]1256            if (!m_View->IsExtendedElevation())
[a9a4db0]1257                m_View->RotateSlower(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1258            break;
1259        case 'R': case 'r':
[eef68f9]1260            if (!m_View->IsExtendedElevation())
[56da40e]1261                OnReverseDirectionOfRotation();
1262            break;
1263        case 'P': case 'p':
[eef68f9]1264            if (!m_View->IsExtendedElevation() && !m_View->ShowingPlan())
[56da40e]1265                OnPlan();
1266            break;
1267        case 'L': case 'l':
[eef68f9]1268            if (!m_View->IsExtendedElevation() && !m_View->ShowingElevation())
[56da40e]1269                OnElevation();
1270            break;
1271        case 'O': case 'o':
1272            OnDisplayOverlappingNames();
1273            break;
1274        case WXK_DELETE:
[de8e9cf]1275            if (e.GetModifiers() == 0)
1276                OnDefaults();
[56da40e]1277            break;
1278        case WXK_RETURN:
[de8e9cf]1279            if (e.GetModifiers() == 0) {
1280                // For compatibility with older versions.
1281                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1282                    m_View->StartRotation();
1283            }
[56da40e]1284            break;
1285        case WXK_SPACE:
[de8e9cf]1286            if (e.GetModifiers() == 0) {
1287                if (!m_View->IsExtendedElevation())
1288                    OnToggleRotation();
1289            }
[56da40e]1290            break;
1291        case WXK_LEFT:
[a6e8d45]1292            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
[eef68f9]1293                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
[a6e8d45]1294                    OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1295            } else {
[a6e8d45]1296                OnShiftDisplayLeft(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1297            }
1298            break;
1299        case WXK_RIGHT:
[a6e8d45]1300            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
[eef68f9]1301                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
[a6e8d45]1302                    OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1303            } else {
[a6e8d45]1304                OnShiftDisplayRight(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1305            }
1306            break;
1307        case WXK_UP:
[a6e8d45]1308            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
[eef68f9]1309                if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
[a6e8d45]1310                    OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1311            } else {
[a6e8d45]1312                OnShiftDisplayUp(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1313            }
1314            break;
1315        case WXK_DOWN:
[a6e8d45]1316            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
[eef68f9]1317                if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
[a6e8d45]1318                    OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1319            } else {
[a6e8d45]1320                OnShiftDisplayDown(e.GetModifiers() == wxMOD_SHIFT);
[56da40e]1321            }
1322            break;
1323        case WXK_ESCAPE:
[de8e9cf]1324            if (e.GetModifiers() == 0) {
1325                if (m_View->ShowingMeasuringLine()) {
1326                    OnCancelDistLine();
1327                } else if (m_View->IsFullScreen()) {
1328                    // Cancel full-screen mode on "Escape" if it isn't cancelling
1329                    // the measuring line.
1330                    m_View->FullScreenMode();
1331                }
[56da40e]1332            }
1333            break;
[d96c95c]1334        case WXK_F2:
[de8e9cf]1335            if (e.GetModifiers() == 0)
1336                m_View->ToggleFatFinger();
[d96c95c]1337            break;
[5e0b3a13]1338        case WXK_F3:
[de8e9cf]1339            if (e.GetModifiers() == 0)
1340                m_View->ToggleHitTestDebug();
[5e0b3a13]1341            break;
[7b9b700]1342        case WXK_F4: {
[de8e9cf]1343            if (e.GetModifiers() == 0) {
1344                const wxChar * msg;
[46d70f6]1345#if wxDEBUG_LEVEL
[de8e9cf]1346                if (wxTheAssertHandler)
1347                    wxTheAssertHandler = NULL;
1348                else
1349                    wxSetDefaultAssertHandler();
1350                if (wxTheAssertHandler)
1351                    msg = wxT("Assertions enabled");
1352                else
1353                    msg = wxT("Assertions disabled");
[46d70f6]1354#else
[de8e9cf]1355                msg = wxT("wxWidgets was built without assertions");
[46d70f6]1356#endif
[de8e9cf]1357                wxMessageBox(msg, wxT("Aven Debug"), wxOK | wxICON_INFORMATION);
1358            }
[cb7ebb5]1359            break;
[7b9b700]1360        }
[c6d5c1c]1361        case WXK_F5:
[de8e9cf]1362            if (e.GetModifiers() == 0) {
1363                m_View->InvalidateAllLists();
1364                m_View->ForceRefresh();
1365            }
[c6d5c1c]1366            break;
[11169cb]1367        case WXK_F6:
[de8e9cf]1368            if (e.GetModifiers() == 0)
1369                m_View->ToggleRenderStats();
[11169cb]1370            break;
[56da40e]1371        default:
1372            e.Skip();
1373    }
[096e56c]1374
[1690fa9]1375    //if (refresh) m_View->ForceRefresh();
[56da40e]1376}
1377
[b13aee4]1378void GUIControl::OnViewFullScreenUpdate(wxUpdateUIEvent& cmd)
1379{
[fdfa926]1380    cmd.Check(m_View->IsFullScreen());
[b13aee4]1381}
1382
1383void GUIControl::OnViewFullScreen()
1384{
1385    m_View->FullScreenMode();
1386}
[f4c5932]1387
1388void GUIControl::OnViewBoundingBoxUpdate(wxUpdateUIEvent& cmd)
1389{
1390    cmd.Enable(m_View->HasData());
1391    cmd.Check(m_View->DisplayingBoundingBox());
1392}
1393
1394void GUIControl::OnViewBoundingBox()
1395{
1396    m_View->ToggleBoundingBox();
1397}
[4938bcd]1398
1399void GUIControl::OnViewTerrainUpdate(wxUpdateUIEvent& cmd)
1400{
1401    cmd.Enable(m_View->HasTerrain());
1402    cmd.Check(m_View->DisplayingTerrain());
1403}
1404
1405void GUIControl::OnViewTerrain()
1406{
1407    m_View->ToggleTerrain();
1408}
Note: See TracBrowser for help on using the repository browser.