source: git/src/guicontrol.cc @ cc9e2c65

RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereostereo-2025walls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since cc9e2c65 was cc9e2c65, checked in by Olly Betts <olly@…>, 10 years ago

lib/,src/: Add "Colour by Gradient".

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