source: git/src/guicontrol.cc @ 76882cb

RELEASE/1.2debug-cidebug-ci-sanitisersstereowalls-data
Last change on this file since 76882cb was 76882cb, checked in by Olly Betts <olly@…>, 11 years ago

src/guicontrol.cc: Fix assertion failure when double-clicking on the
survey with wx2.9.

  • Property mode set to 100644
File size: 28.1 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 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->SetCursor(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->SetCursor(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->SetCursor(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->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
123            } else {
124                m_ScaleRotateLock = lock_SCALE;
125//              m_View->SetCursor(GfxCore::CURSOR_ZOOM);
126            }
127            break;
128        case lock_SCALE:
129            if (dx2 >= 8 * dy2) {
130                m_ScaleRotateLock = lock_ROTATE;
131//              m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
132            }
133            break;
134        case lock_ROTATE:
135            if (dy2 >= 8 * dx2) {
136                m_ScaleRotateLock = lock_SCALE;
137//              m_View->SetCursor(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->SetCursor(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->SetCursor(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->SetCursor(GfxCore::CURSOR_POINTING_HAND);
220    } else {
221        m_View->SetCursor(GfxCore::CURSOR_DEFAULT);
222    }
223}
224
225void GUIControl::HandleNonDrag(const wxPoint & point) {
226    if (m_View->CheckHitTestGrid(point, false)) {
227        m_View->SetCursor(GfxCore::CURSOR_POINTING_HAND);
228    } else if (m_View->PointWithinScaleBar(point)) {
229        m_View->SetCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE);
230    } else if (m_View->PointWithinCompass(point)) {
231        m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
232    } else if (m_View->PointWithinClino(point)) {
233        m_View->SetCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
234    } else {
235        RestoreCursor();
236    }
237}
238
239//
240//  Mouse event handling methods
241//
242
243void GUIControl::OnMouseMove(wxMouseEvent& event)
244{
245    // Mouse motion event handler.
246    if (!m_View->HasData()) return;
247
248    // Ignore moves which don't change the position.
249    if (event.GetPosition() == m_DragStart) {
250        return;
251    }
252
253    static long timestamp = LONG_MIN;
254    if (dragging != NO_DRAG && m_ScaleRotateLock != lock_NONE &&
255        timestamp != LONG_MIN) {
256        // If no motion for a second, reset the direction lock.
257        if (event.GetTimestamp() - timestamp >= 1000) {
258            m_ScaleRotateLock = lock_NONE;
259            m_DragRealStart = m_DragStart;
260            RestoreCursor();
261        }
262    }
263    timestamp = event.GetTimestamp();
264
265    wxPoint point(event.GetPosition());
266
267    // Check hit-test grid (only if no buttons are pressed).
268    if (!event.LeftIsDown() && !event.MiddleIsDown() && !event.RightIsDown()) {
269        HandleNonDrag(point);
270    }
271
272    // Update coordinate display if in plan view,
273    // or altitude if in elevation view.
274    m_View->SetCoords(point);
275
276    switch (dragging) {
277        case LEFT_DRAG:
278            switch (m_LastDrag) {
279                case drag_COMPASS:
280                    // Drag in heading indicator.
281                    m_View->SetCompassFromPoint(point);
282                    break;
283                case drag_ELEV:
284                    // Drag in clinometer.
285                    m_View->SetClinoFromPoint(point);
286                    break;
287                case drag_SCALE:
288                    m_View->SetScaleBarFromOffset(point.x - m_DragLast.x);
289                    break;
290                case drag_MAIN:
291                    if (event.ControlDown()) {
292                        HandleTiltRotate(point);
293                    } else {
294                        HandleScaleRotate(point);
295                    }
296                    break;
297                case drag_NONE:
298                    // Shouldn't happen?!  FIXME: assert or something.
299                    break;
300            }
301            break;
302        case MIDDLE_DRAG:
303            HandleTilt(point);
304            break;
305        case RIGHT_DRAG:
306            HandleTranslate(point);
307            break;
308        case NO_DRAG:
309            break;
310    }
311
312    m_DragLast = point;
313}
314
315void GUIControl::OnLButtonDown(wxMouseEvent& event)
316{
317    if (m_View->HasData()) {
318        dragging = LEFT_DRAG;
319
320        m_DragStart = m_DragRealStart = event.GetPosition();
321
322        if (m_View->PointWithinCompass(m_DragStart)) {
323            m_LastDrag = drag_COMPASS;
324        } else if (m_View->PointWithinClino(m_DragStart)) {
325            m_LastDrag = drag_ELEV;
326        } else if (m_View->PointWithinScaleBar(m_DragStart)) {
327            m_LastDrag = drag_SCALE;
328        } else {
329            if (event.ControlDown()) {
330                if (m_View->IsExtendedElevation()) {
331                    dragging = NO_DRAG;
332                    return;
333                }
334                m_View->SetCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY);
335            } else {
336                m_View->SetCursor(GfxCore::CURSOR_ZOOM_ROTATE);
337            }
338
339            m_LastDrag = drag_MAIN;
340            m_ScaleRotateLock = lock_NONE;
341        }
342
343        m_View->CaptureMouse();
344    }
345}
346
347void GUIControl::OnLButtonUp(wxMouseEvent& event)
348{
349    if (m_View->HasData()) {
350        if (dragging == NO_DRAG)
351            return;
352
353        if (event.GetPosition() == m_DragRealStart) {
354            // Just a "click"...
355            m_View->CheckHitTestGrid(m_DragStart, true);
356        }
357
358//      m_View->RedrawIndicators();
359        m_View->ReleaseMouse();
360
361        m_LastDrag = drag_NONE;
362        dragging = NO_DRAG;
363
364        m_View->DragFinished();
365
366        if (event.GetPosition() == m_DragRealStart) {
367            RestoreCursor();
368        } else {
369            HandleNonDrag(event.GetPosition());
370        }
371    }
372}
373
374void GUIControl::OnMButtonDown(wxMouseEvent& event)
375{
376    if (m_View->HasData() && !m_View->IsExtendedElevation()) {
377        dragging = MIDDLE_DRAG;
378        m_DragStart = event.GetPosition();
379
380        m_View->SetCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
381
382        m_View->CaptureMouse();
383    }
384}
385
386void GUIControl::OnMButtonUp(wxMouseEvent&)
387{
388    if (m_View->HasData()) {
389        dragging = NO_DRAG;
390        m_View->ReleaseMouse();
391        m_View->DragFinished();
392
393        RestoreCursor();
394    }
395}
396
397void GUIControl::OnRButtonDown(wxMouseEvent& event)
398{
399    if (m_View->HasData()) {
400        if (m_View->HandleRClick(event.GetPosition()))
401            return;
402
403        m_DragStart = event.GetPosition();
404
405        dragging = RIGHT_DRAG;
406
407        m_View->SetCursor(GfxCore::CURSOR_DRAGGING_HAND);
408        m_View->CaptureMouse();
409    }
410}
411
412void GUIControl::OnRButtonUp(wxMouseEvent&)
413{
414    m_LastDrag = drag_NONE;
415    m_View->ReleaseMouse();
416
417    dragging = NO_DRAG;
418
419    RestoreCursor();
420
421    m_View->DragFinished();
422}
423
424void GUIControl::OnMouseWheel(wxMouseEvent& event) {
425    int dy = event.GetWheelRotation();
426    if (m_View->GetPerspective()) {
427        m_View->MoveViewer(-dy, 0, 0);
428    } else {
429        m_View->SetScale(m_View->GetScale() * pow(1.06, -0.04 * dy));
430        m_View->ForceRefresh();
431    }
432}
433
434void GUIControl::OnDisplayOverlappingNames()
435{
436    m_View->ToggleOverlappingNames();
437}
438
439void GUIControl::OnDisplayOverlappingNamesUpdate(wxUpdateUIEvent& cmd)
440{
441    cmd.Enable(m_View->HasData() && m_View->ShowingStationNames());
442    cmd.Check(m_View->ShowingOverlappingNames());
443}
444
445void GUIControl::OnColourByDepth()
446{
447    if (m_View->ColouringBy() == COLOUR_BY_DEPTH) {
448        m_View->SetColourBy(COLOUR_BY_NONE);
449    } else {
450        m_View->SetColourBy(COLOUR_BY_DEPTH);
451    }
452}
453
454void GUIControl::OnColourByDate()
455{
456    if (m_View->ColouringBy() == COLOUR_BY_DATE) {
457        m_View->SetColourBy(COLOUR_BY_NONE);
458    } else {
459        m_View->SetColourBy(COLOUR_BY_DATE);
460    }
461}
462
463void GUIControl::OnColourByError()
464{
465    if (m_View->ColouringBy() == COLOUR_BY_ERROR) {
466        m_View->SetColourBy(COLOUR_BY_NONE);
467    } else {
468        m_View->SetColourBy(COLOUR_BY_ERROR);
469    }
470}
471
472void GUIControl::OnColourByDepthUpdate(wxUpdateUIEvent& cmd)
473{
474    cmd.Enable(m_View->HasData());
475    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DEPTH);
476}
477
478void GUIControl::OnColourByDateUpdate(wxUpdateUIEvent& cmd)
479{
480    cmd.Enable(m_View->HasData());
481    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DATE);
482}
483
484void GUIControl::OnColourByErrorUpdate(wxUpdateUIEvent& cmd)
485{
486    cmd.Enable(m_View->HasData());
487    cmd.Check(m_View->ColouringBy() == COLOUR_BY_ERROR);
488}
489
490void GUIControl::OnShowCrosses()
491{
492    m_View->ToggleCrosses();
493}
494
495void GUIControl::OnShowCrossesUpdate(wxUpdateUIEvent& cmd)
496{
497    cmd.Enable(m_View->HasData());
498    cmd.Check(m_View->ShowingCrosses());
499}
500
501void GUIControl::OnShowStationNames()
502{
503    m_View->ToggleStationNames();
504}
505
506void GUIControl::OnShowStationNamesUpdate(wxUpdateUIEvent& cmd)
507{
508    cmd.Enable(m_View->HasData());
509    cmd.Check(m_View->ShowingStationNames());
510}
511
512void GUIControl::OnShowSurveyLegs()
513{
514    m_View->ToggleUndergroundLegs();
515}
516
517void GUIControl::OnShowSurveyLegsUpdate(wxUpdateUIEvent& cmd)
518{
519    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs());
520    cmd.Check(m_View->ShowingUndergroundLegs());
521}
522
523void GUIControl::OnHideSplays()
524{
525    m_View->SetSplaysMode(SPLAYS_HIDE);
526}
527
528void GUIControl::OnShowSplaysNormal()
529{
530    m_View->SetSplaysMode(SPLAYS_SHOW_NORMAL);
531}
532
533void GUIControl::OnShowSplaysFaded()
534{
535    m_View->SetSplaysMode(SPLAYS_SHOW_FADED);
536}
537
538void GUIControl::OnSplaysUpdate(wxUpdateUIEvent& cmd)
539{
540    cmd.Enable(m_View->HasData() && m_View->HasSplays());
541}
542
543void GUIControl::OnHideSplaysUpdate(wxUpdateUIEvent& cmd)
544{
545    cmd.Enable(m_View->HasData() && m_View->HasSplays());
546    cmd.Check(m_View->ShowingSplaysMode() == SPLAYS_HIDE);
547}
548
549void GUIControl::OnShowSplaysNormalUpdate(wxUpdateUIEvent& cmd)
550{
551    cmd.Enable(m_View->HasData() && m_View->HasSplays());
552    cmd.Check(m_View->ShowingSplaysMode() == SPLAYS_SHOW_NORMAL);
553}
554
555void GUIControl::OnShowSplaysFadedUpdate(wxUpdateUIEvent& cmd)
556{
557    cmd.Enable(m_View->HasData() && m_View->HasSplays());
558    cmd.Check(m_View->ShowingSplaysMode() == SPLAYS_SHOW_FADED);
559}
560
561void GUIControl::OnMoveEast()
562{
563    m_View->TurnCaveTo(90.0);
564    m_View->ForceRefresh();
565}
566
567void GUIControl::OnMoveEastUpdate(wxUpdateUIEvent& cmd)
568{
569    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 90.0);
570}
571
572void GUIControl::OnMoveNorth()
573{
574    m_View->TurnCaveTo(0.0);
575    m_View->ForceRefresh();
576}
577
578void GUIControl::OnMoveNorthUpdate(wxUpdateUIEvent& cmd)
579{
580    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 0.0);
581}
582
583void GUIControl::OnMoveSouth()
584{
585    m_View->TurnCaveTo(180.0);
586    m_View->ForceRefresh();
587}
588
589void GUIControl::OnMoveSouthUpdate(wxUpdateUIEvent& cmd)
590{
591    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 180.0);
592}
593
594void GUIControl::OnMoveWest()
595{
596    m_View->TurnCaveTo(270.0);
597    m_View->ForceRefresh();
598}
599
600void GUIControl::OnMoveWestUpdate(wxUpdateUIEvent& cmd)
601{
602    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 270.0);
603}
604
605void GUIControl::OnToggleRotation()
606{
607    m_View->ToggleRotation();
608}
609
610void GUIControl::OnToggleRotationUpdate(wxUpdateUIEvent& cmd)
611{
612    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
613    cmd.Check(m_View->HasData() && m_View->IsRotating());
614}
615
616void GUIControl::OnReverseControls()
617{
618    m_ReverseControls = !m_ReverseControls;
619}
620
621void GUIControl::OnReverseControlsUpdate(wxUpdateUIEvent& cmd)
622{
623    cmd.Enable(m_View->HasData());
624    cmd.Check(m_ReverseControls);
625}
626
627void GUIControl::OnReverseDirectionOfRotation()
628{
629    m_View->ReverseRotation();
630}
631
632void GUIControl::OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent& cmd)
633{
634    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
635}
636
637void GUIControl::OnSlowDown(bool accel)
638{
639    m_View->RotateSlower(accel);
640}
641
642void GUIControl::OnSlowDownUpdate(wxUpdateUIEvent& cmd)
643{
644    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
645}
646
647void GUIControl::OnSpeedUp(bool accel)
648{
649    m_View->RotateFaster(accel);
650}
651
652void GUIControl::OnSpeedUpUpdate(wxUpdateUIEvent& cmd)
653{
654    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
655}
656
657void GUIControl::OnStepOnceAnticlockwise(bool accel)
658{
659    if (m_View->GetPerspective()) {
660        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
661    } else {
662        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
663    }
664    m_View->ForceRefresh();
665}
666
667void GUIControl::OnStepOnceAnticlockwiseUpdate(wxUpdateUIEvent& cmd)
668{
669    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->IsRotating());
670}
671
672void GUIControl::OnStepOnceClockwise(bool accel)
673{
674    if (m_View->GetPerspective()) {
675        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
676    } else {
677        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
678    }
679    m_View->ForceRefresh();
680}
681
682void GUIControl::OnStepOnceClockwiseUpdate(wxUpdateUIEvent& cmd)
683{
684    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->IsRotating());
685}
686
687void GUIControl::OnDefaults()
688{
689    m_View->Defaults();
690}
691
692void GUIControl::OnDefaultsUpdate(wxUpdateUIEvent& cmd)
693{
694    cmd.Enable(m_View->HasData());
695}
696
697void GUIControl::OnElevation()
698{
699    // Switch to elevation view.
700
701    m_View->SwitchToElevation();
702}
703
704void GUIControl::OnElevationUpdate(wxUpdateUIEvent& cmd)
705{
706    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingElevation());
707}
708
709void GUIControl::OnHigherViewpoint(bool accel)
710{
711    // Raise the viewpoint.
712    if (m_View->GetPerspective()) {
713        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
714    } else {
715        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
716    }
717    m_View->ForceRefresh();
718}
719
720void GUIControl::OnHigherViewpointUpdate(wxUpdateUIEvent& cmd)
721{
722    cmd.Enable(m_View->HasData() && m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation());
723}
724
725void GUIControl::OnLowerViewpoint(bool accel)
726{
727    // Lower the viewpoint.
728    if (m_View->GetPerspective()) {
729        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
730    } else {
731        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
732    }
733    m_View->ForceRefresh();
734}
735
736void GUIControl::OnLowerViewpointUpdate(wxUpdateUIEvent& cmd)
737{
738    cmd.Enable(m_View->HasData() && m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation());
739}
740
741void GUIControl::OnPlan()
742{
743    // Switch to plan view.
744    m_View->SwitchToPlan();
745}
746
747void GUIControl::OnPlanUpdate(wxUpdateUIEvent& cmd)
748{
749    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingPlan());
750}
751
752void GUIControl::OnShiftDisplayDown(bool accel)
753{
754    if (m_View->GetPerspective())
755        m_View->MoveViewer(0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0);
756    else
757        m_View->TranslateCave(0, accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT);
758}
759
760void GUIControl::OnShiftDisplayDownUpdate(wxUpdateUIEvent& cmd)
761{
762    cmd.Enable(m_View->HasData());
763}
764
765void GUIControl::OnShiftDisplayLeft(bool accel)
766{
767    if (m_View->GetPerspective())
768        m_View->MoveViewer(0, 0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT);
769    else
770        m_View->TranslateCave(accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT, 0);
771}
772
773void GUIControl::OnShiftDisplayLeftUpdate(wxUpdateUIEvent& cmd)
774{
775    cmd.Enable(m_View->HasData());
776}
777
778void GUIControl::OnShiftDisplayRight(bool accel)
779{
780    if (m_View->GetPerspective())
781        m_View->MoveViewer(0, 0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT);
782    else
783        m_View->TranslateCave(accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT, 0);
784}
785
786void GUIControl::OnShiftDisplayRightUpdate(wxUpdateUIEvent& cmd)
787{
788    cmd.Enable(m_View->HasData());
789}
790
791void GUIControl::OnShiftDisplayUp(bool accel)
792{
793    if (m_View->GetPerspective())
794        m_View->MoveViewer(0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0);
795    else
796        m_View->TranslateCave(0, accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT);
797}
798
799void GUIControl::OnShiftDisplayUpUpdate(wxUpdateUIEvent& cmd)
800{
801    cmd.Enable(m_View->HasData());
802}
803
804void GUIControl::OnZoomIn(bool accel)
805{
806    // Increase the scale.
807
808    if (m_View->GetPerspective()) {
809        m_View->MoveViewer(accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0, 0);
810    } else {
811        m_View->SetScale(m_View->GetScale() * (accel ? 1.1236 : 1.06));
812        m_View->ForceRefresh();
813    }
814}
815
816void GUIControl::OnZoomInUpdate(wxUpdateUIEvent& cmd)
817{
818    cmd.Enable(m_View->HasData());
819}
820
821void GUIControl::OnZoomOut(bool accel)
822{
823    // Decrease the scale.
824
825    if (m_View->GetPerspective()) {
826        m_View->MoveViewer(accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0, 0);
827    } else {
828        m_View->SetScale(m_View->GetScale() / (accel ? 1.1236 : 1.06));
829        m_View->ForceRefresh();
830    }
831}
832
833void GUIControl::OnZoomOutUpdate(wxUpdateUIEvent& cmd)
834{
835    cmd.Enable(m_View->HasData());
836}
837
838void GUIControl::OnToggleScalebar()
839{
840    m_View->ToggleScaleBar();
841}
842
843void GUIControl::OnToggleScalebarUpdate(wxUpdateUIEvent& cmd)
844{
845    cmd.Enable(m_View->HasData());
846    cmd.Check(m_View->ShowingScaleBar());
847}
848
849void GUIControl::OnToggleColourKey()
850{
851    m_View->ToggleColourKey();
852}
853
854void GUIControl::OnToggleColourKeyUpdate(wxUpdateUIEvent& cmd)
855{
856    cmd.Enable(m_View->HasData() && m_View->ColouringBy() != COLOUR_BY_NONE);
857    cmd.Check(m_View->ShowingColourKey());
858}
859
860void GUIControl::OnViewCompass()
861{
862    m_View->ToggleCompass();
863}
864
865void GUIControl::OnViewCompassUpdate(wxUpdateUIEvent& cmd)
866{
867    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
868    cmd.Check(m_View->ShowingCompass());
869}
870
871void GUIControl::OnViewClino()
872{
873    m_View->ToggleClino();
874}
875
876void GUIControl::OnViewClinoUpdate(wxUpdateUIEvent& cmd)
877{
878    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
879    cmd.Check(m_View->ShowingClino());
880}
881
882void GUIControl::OnShowSurface()
883{
884    m_View->ToggleSurfaceLegs();
885}
886
887void GUIControl::OnShowSurfaceUpdate(wxUpdateUIEvent& cmd)
888{
889    cmd.Enable(m_View->HasData() && m_View->HasSurfaceLegs());
890    cmd.Check(m_View->ShowingSurfaceLegs());
891}
892
893void GUIControl::OnShowEntrances()
894{
895    m_View->ToggleEntrances();
896}
897
898void GUIControl::OnShowEntrancesUpdate(wxUpdateUIEvent& cmd)
899{
900    cmd.Enable(m_View->HasData() && (m_View->GetNumEntrances() > 0));
901    cmd.Check(m_View->ShowingEntrances());
902}
903
904void GUIControl::OnShowFixedPts()
905{
906    m_View->ToggleFixedPts();
907}
908
909void GUIControl::OnShowFixedPtsUpdate(wxUpdateUIEvent& cmd)
910{
911    cmd.Enable(m_View->HasData() && (m_View->GetNumFixedPts() > 0));
912    cmd.Check(m_View->ShowingFixedPts());
913}
914
915void GUIControl::OnShowExportedPts()
916{
917    m_View->ToggleExportedPts();
918}
919
920void GUIControl::OnShowExportedPtsUpdate(wxUpdateUIEvent& cmd)
921{
922    cmd.Enable(m_View->HasData() && (m_View->GetNumExportedPts() > 0));
923    cmd.Check(m_View->ShowingExportedPts());
924}
925
926void GUIControl::OnViewGrid()
927{
928    m_View->ToggleGrid();
929}
930
931void GUIControl::OnViewGridUpdate(wxUpdateUIEvent& cmd)
932{
933    cmd.Enable(m_View->HasData());
934    cmd.Check(m_View->ShowingGrid());
935}
936
937void GUIControl::OnIndicatorsUpdate(wxUpdateUIEvent& cmd)
938{
939    cmd.Enable(m_View->HasData());
940}
941
942void GUIControl::OnViewPerspective()
943{
944    m_View->TogglePerspective();
945    // Force update of coordinate display.
946    if (m_View->GetPerspective()) {
947        m_View->MoveViewer(0, 0, 0);
948    } else {
949        m_View->ClearCoords();
950    }
951}
952
953void GUIControl::OnViewPerspectiveUpdate(wxUpdateUIEvent& cmd)
954{
955    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
956    cmd.Check(m_View->GetPerspective());
957}
958
959void GUIControl::OnViewSmoothShading()
960{
961    m_View->ToggleSmoothShading();
962}
963
964void GUIControl::OnViewSmoothShadingUpdate(wxUpdateUIEvent& cmd)
965{
966    cmd.Enable(m_View->HasData());
967    cmd.Check(m_View->GetSmoothShading());
968}
969
970void GUIControl::OnViewTextured()
971{
972    m_View->ToggleTextured();
973}
974
975void GUIControl::OnViewTexturedUpdate(wxUpdateUIEvent& cmd)
976{
977    cmd.Enable(m_View->HasData());
978    cmd.Check(m_View->GetTextured());
979}
980
981void GUIControl::OnViewFog()
982{
983    m_View->ToggleFog();
984}
985
986void GUIControl::OnViewFogUpdate(wxUpdateUIEvent& cmd)
987{
988    cmd.Enable(m_View->HasData());
989    cmd.Check(m_View->GetFog());
990}
991
992void GUIControl::OnViewSmoothLines()
993{
994    m_View->ToggleAntiAlias();
995}
996
997void GUIControl::OnViewSmoothLinesUpdate(wxUpdateUIEvent& cmd)
998{
999    cmd.Enable(m_View->HasData());
1000    cmd.Check(m_View->GetAntiAlias());
1001}
1002
1003void GUIControl::OnToggleMetric()
1004{
1005    m_View->ToggleMetric();
1006
1007    wxConfigBase::Get()->Write(wxT("metric"), m_View->GetMetric());
1008    wxConfigBase::Get()->Flush();
1009}
1010
1011void GUIControl::OnToggleMetricUpdate(wxUpdateUIEvent& cmd)
1012{
1013    cmd.Enable(m_View->HasData());
1014    cmd.Check(m_View->GetMetric());
1015}
1016
1017void GUIControl::OnToggleDegrees()
1018{
1019    m_View->ToggleDegrees();
1020
1021    wxConfigBase::Get()->Write(wxT("degrees"), m_View->GetDegrees());
1022    wxConfigBase::Get()->Flush();
1023}
1024
1025void GUIControl::OnToggleDegreesUpdate(wxUpdateUIEvent& cmd)
1026{
1027    cmd.Enable(m_View->HasData());
1028    cmd.Check(m_View->GetDegrees());
1029}
1030
1031void GUIControl::OnToggleTubes()
1032{
1033    m_View->ToggleTubes();
1034}
1035
1036void GUIControl::OnToggleTubesUpdate(wxUpdateUIEvent& cmd)
1037{
1038    cmd.Enable(m_View->HasData() && m_View->HasTubes());
1039    cmd.Check(m_View->GetTubes());
1040}
1041
1042void GUIControl::OnCancelDistLine()
1043{
1044    m_View->ClearTreeSelection();
1045}
1046
1047void GUIControl::OnCancelDistLineUpdate(wxUpdateUIEvent& cmd)
1048{
1049    cmd.Enable(m_View->ShowingMeasuringLine());
1050}
1051
1052void GUIControl::OnKeyPress(wxKeyEvent &e)
1053{
1054    if (!m_View->HasData()) {
1055        e.Skip();
1056        return;
1057    }
1058
1059    // The changelog says this is meant to keep animation going while keys are
1060    // pressed, but that happens anyway (on linux at least - perhaps it helps
1061    // on windows?)  FIXME : check!
1062    //bool refresh = m_View->Animate();
1063
1064    switch (e.GetKeyCode()) {
1065        case '/': case '?':
1066            if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
1067                OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1068            break;
1069        case '\'': case '@': case '"': // both shifted forms - US and UK kbd
1070            if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
1071                OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1072            break;
1073        case 'C': case 'c':
1074            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1075                OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
1076            break;
1077        case 'V': case 'v':
1078            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1079                OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
1080            break;
1081        case ']': case '}':
1082            OnZoomIn(e.GetModifiers() == wxMOD_SHIFT);
1083            break;
1084        case '[': case '{':
1085            OnZoomOut(e.GetModifiers() == wxMOD_SHIFT);
1086            break;
1087        case 'N': case 'n':
1088            OnMoveNorth();
1089            break;
1090        case 'S': case 's':
1091            OnMoveSouth();
1092            break;
1093        case 'E': case 'e':
1094            if (!m_View->IsExtendedElevation())
1095                OnMoveEast();
1096            break;
1097        case 'W': case 'w':
1098            if (!m_View->IsExtendedElevation())
1099                OnMoveWest();
1100            break;
1101        case 'Z': case 'z':
1102            if (!m_View->IsExtendedElevation())
1103                OnSpeedUp(e.GetModifiers() == wxMOD_SHIFT);
1104            break;
1105        case 'X': case 'x':
1106            if (!m_View->IsExtendedElevation())
1107                OnSlowDown(e.GetModifiers() == wxMOD_SHIFT);
1108            break;
1109        case 'R': case 'r':
1110            if (!m_View->IsExtendedElevation())
1111                OnReverseDirectionOfRotation();
1112            break;
1113        case 'P': case 'p':
1114            if (!m_View->IsExtendedElevation() && !m_View->ShowingPlan())
1115                OnPlan();
1116            break;
1117        case 'L': case 'l':
1118            if (!m_View->IsExtendedElevation() && !m_View->ShowingElevation())
1119                OnElevation();
1120            break;
1121        case 'O': case 'o':
1122            OnDisplayOverlappingNames();
1123            break;
1124        case WXK_DELETE:
1125            OnDefaults();
1126            break;
1127        case WXK_RETURN:
1128            // For compatibility with older versions.
1129            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1130                m_View->StartRotation();
1131            break;
1132        case WXK_SPACE:
1133            if (!m_View->IsExtendedElevation())
1134                OnToggleRotation();
1135            break;
1136        case WXK_LEFT:
1137            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1138                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1139                    OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
1140            } else {
1141                OnShiftDisplayLeft(e.GetModifiers() == wxMOD_SHIFT);
1142            }
1143            break;
1144        case WXK_RIGHT:
1145            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1146                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1147                    OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
1148            } else {
1149                OnShiftDisplayRight(e.GetModifiers() == wxMOD_SHIFT);
1150            }
1151            break;
1152        case WXK_UP:
1153            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1154                if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
1155                    OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1156            } else {
1157                OnShiftDisplayUp(e.GetModifiers() == wxMOD_SHIFT);
1158            }
1159            break;
1160        case WXK_DOWN:
1161            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1162                if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
1163                    OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1164            } else {
1165                OnShiftDisplayDown(e.GetModifiers() == wxMOD_SHIFT);
1166            }
1167            break;
1168        case WXK_ESCAPE:
1169            if (m_View->ShowingMeasuringLine()) {
1170                OnCancelDistLine();
1171            }
1172            break;
1173        case WXK_F5:
1174            m_View->InvalidateAllLists();
1175            m_View->ForceRefresh();
1176            break;
1177        default:
1178            e.Skip();
1179    }
1180
1181    //if (refresh) m_View->ForceRefresh();
1182}
1183
1184void GUIControl::OnViewFullScreenUpdate(wxUpdateUIEvent& cmd)
1185{
1186    cmd.Check(m_View->IsFullScreen());
1187}
1188
1189void GUIControl::OnViewFullScreen()
1190{
1191    m_View->FullScreenMode();
1192}
1193
1194void GUIControl::OnViewBoundingBoxUpdate(wxUpdateUIEvent& cmd)
1195{
1196    cmd.Enable(m_View->HasData());
1197    cmd.Check(m_View->DisplayingBoundingBox());
1198}
1199
1200void GUIControl::OnViewBoundingBox()
1201{
1202    m_View->ToggleBoundingBox();
1203}
Note: See TracBrowser for help on using the repository browser.