source: git/src/guicontrol.cc @ 68fb07a

Last change on this file since 68fb07a was 68fb07a, checked in by Olly Betts <olly@…>, 15 months ago

Add basic "Colour by Survey"

Colours aren't currently controllable.

  • Property mode set to 100644
File size: 32.4 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,2016 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.MiddleIsDown()) {
372            if (m_LastDrag == drag_ZOOM)
373                m_View->UnsetZoomBox();
374            OnMButtonDown(event);
375            return;
376        }
377
378        if (event.RightIsDown()) {
379            if (m_LastDrag == drag_ZOOM)
380                m_View->UnsetZoomBox();
381            OnRButtonDown(event);
382            return;
383        }
384
385        if (m_LastDrag == drag_ZOOM) {
386            m_View->ZoomBoxGo();
387        }
388
389        m_View->ReleaseMouse();
390
391        m_LastDrag = drag_NONE;
392        dragging = NO_DRAG;
393
394        m_View->DragFinished();
395
396        if (event.GetPosition() == m_DragRealStart) {
397            // Just a "click"...
398            m_View->CheckHitTestGrid(m_DragStart, true);
399            RestoreCursor();
400        } else {
401            HandleNonDrag(event.GetPosition());
402        }
403    }
404}
405
406void GUIControl::OnMButtonDown(wxMouseEvent& event)
407{
408    if (m_View->HasData() && !m_View->IsExtendedElevation()) {
409        m_DragStart = event.GetPosition();
410
411        m_View->UpdateCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
412
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        }
420        m_View->CaptureMouse();
421        dragging = MIDDLE_DRAG;
422    }
423}
424
425void GUIControl::OnMButtonUp(wxMouseEvent& event)
426{
427    if (m_View->HasData()) {
428        if (dragging != MIDDLE_DRAG)
429            return;
430
431        if (event.LeftIsDown()) {
432            OnLButtonDown(event);
433            return;
434        }
435
436        if (event.RightIsDown()) {
437            OnRButtonDown(event);
438            return;
439        }
440
441        dragging = NO_DRAG;
442        m_View->ReleaseMouse();
443        m_View->DragFinished();
444
445        RestoreCursor();
446    }
447}
448
449void GUIControl::OnRButtonDown(wxMouseEvent& event)
450{
451    if (m_View->HasData()) {
452        if (m_View->HandleRClick(event.GetPosition()))
453            return;
454
455        m_DragStart = event.GetPosition();
456
457        m_View->UpdateCursor(GfxCore::CURSOR_DRAGGING_HAND);
458
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        }
466        m_View->CaptureMouse();
467        dragging = RIGHT_DRAG;
468    }
469}
470
471void GUIControl::OnRButtonUp(wxMouseEvent& event)
472{
473    if (dragging != RIGHT_DRAG)
474        return;
475
476    if (event.LeftIsDown()) {
477        OnLButtonDown(event);
478        return;
479    }
480
481    if (event.MiddleIsDown()) {
482        OnMButtonDown(event);
483        return;
484    }
485
486    m_LastDrag = drag_NONE;
487    m_View->ReleaseMouse();
488
489    dragging = NO_DRAG;
490
491    RestoreCursor();
492
493    m_View->DragFinished();
494}
495
496void GUIControl::OnMouseWheel(wxMouseEvent& event) {
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));
502        m_View->ForceRefresh();
503    }
504}
505
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
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
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
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
544void GUIControl::OnColourByGradient()
545{
546    if (m_View->ColouringBy() == COLOUR_BY_GRADIENT) {
547        m_View->SetColourBy(COLOUR_BY_NONE);
548    } else {
549        m_View->SetColourBy(COLOUR_BY_GRADIENT);
550    }
551}
552
553void GUIControl::OnColourByLength()
554{
555    if (m_View->ColouringBy() == COLOUR_BY_LENGTH) {
556        m_View->SetColourBy(COLOUR_BY_NONE);
557    } else {
558        m_View->SetColourBy(COLOUR_BY_LENGTH);
559    }
560}
561
562void GUIControl::OnColourBySurvey()
563{
564    if (m_View->ColouringBy() == COLOUR_BY_SURVEY) {
565        m_View->SetColourBy(COLOUR_BY_NONE);
566    } else {
567        m_View->SetColourBy(COLOUR_BY_SURVEY);
568    }
569}
570
571void GUIControl::OnColourByUpdate(wxUpdateUIEvent& cmd)
572{
573    cmd.Enable(m_View->HasData());
574}
575
576void GUIControl::OnColourByDepthUpdate(wxUpdateUIEvent& cmd)
577{
578    cmd.Enable(m_View->HasData());
579    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DEPTH);
580}
581
582void GUIControl::OnColourByDateUpdate(wxUpdateUIEvent& cmd)
583{
584    cmd.Enable(m_View->HasData());
585    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DATE);
586}
587
588void GUIControl::OnColourByErrorUpdate(wxUpdateUIEvent& cmd)
589{
590    cmd.Enable(m_View->HasData());
591    cmd.Check(m_View->ColouringBy() == COLOUR_BY_ERROR);
592}
593
594void GUIControl::OnColourByGradientUpdate(wxUpdateUIEvent& cmd)
595{
596    cmd.Enable(m_View->HasData());
597    cmd.Check(m_View->ColouringBy() == COLOUR_BY_GRADIENT);
598}
599
600void GUIControl::OnColourByLengthUpdate(wxUpdateUIEvent& cmd)
601{
602    cmd.Enable(m_View->HasData());
603    cmd.Check(m_View->ColouringBy() == COLOUR_BY_LENGTH);
604}
605
606void GUIControl::OnColourBySurveyUpdate(wxUpdateUIEvent& cmd)
607{
608    cmd.Enable(m_View->HasData());
609    cmd.Check(m_View->ColouringBy() == COLOUR_BY_SURVEY);
610}
611
612void GUIControl::OnShowCrosses()
613{
614    m_View->ToggleCrosses();
615}
616
617void GUIControl::OnShowCrossesUpdate(wxUpdateUIEvent& cmd)
618{
619    cmd.Enable(m_View->HasData());
620    cmd.Check(m_View->ShowingCrosses());
621}
622
623void GUIControl::OnShowStationNames()
624{
625    m_View->ToggleStationNames();
626}
627
628void GUIControl::OnShowStationNamesUpdate(wxUpdateUIEvent& cmd)
629{
630    cmd.Enable(m_View->HasData());
631    cmd.Check(m_View->ShowingStationNames());
632}
633
634void GUIControl::OnShowSurveyLegs()
635{
636    m_View->ToggleUndergroundLegs();
637}
638
639void GUIControl::OnShowSurveyLegsUpdate(wxUpdateUIEvent& cmd)
640{
641    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs());
642    cmd.Check(m_View->ShowingUndergroundLegs());
643}
644
645void GUIControl::OnHideSplays()
646{
647    m_View->SetSplaysMode(SHOW_HIDE);
648}
649
650void GUIControl::OnShowSplaysDashed()
651{
652    m_View->SetSplaysMode(SHOW_DASHED);
653}
654
655void GUIControl::OnShowSplaysFaded()
656{
657    m_View->SetSplaysMode(SHOW_FADED);
658}
659
660void GUIControl::OnShowSplaysNormal()
661{
662    m_View->SetSplaysMode(SHOW_NORMAL);
663}
664
665void GUIControl::OnSplaysUpdate(wxUpdateUIEvent& cmd)
666{
667    cmd.Enable(m_View->HasData() && m_View->HasSplays());
668}
669
670void GUIControl::OnHideSplaysUpdate(wxUpdateUIEvent& cmd)
671{
672    cmd.Enable(m_View->HasData() && m_View->HasSplays());
673    cmd.Check(m_View->ShowingSplaysMode() == SHOW_HIDE);
674}
675
676void GUIControl::OnShowSplaysDashedUpdate(wxUpdateUIEvent& cmd)
677{
678    cmd.Enable(m_View->HasData() && m_View->HasSplays());
679    cmd.Check(m_View->ShowingSplaysMode() == SHOW_DASHED);
680}
681
682void GUIControl::OnShowSplaysFadedUpdate(wxUpdateUIEvent& cmd)
683{
684    cmd.Enable(m_View->HasData() && m_View->HasSplays());
685    cmd.Check(m_View->ShowingSplaysMode() == SHOW_FADED);
686}
687
688void GUIControl::OnShowSplaysNormalUpdate(wxUpdateUIEvent& cmd)
689{
690    cmd.Enable(m_View->HasData() && m_View->HasSplays());
691    cmd.Check(m_View->ShowingSplaysMode() == SHOW_NORMAL);
692}
693
694void GUIControl::OnHideDupes() {
695    m_View->SetDupesMode(SHOW_HIDE);
696}
697
698void GUIControl::OnShowDupesDashed() {
699    m_View->SetDupesMode(SHOW_DASHED);
700}
701
702void GUIControl::OnShowDupesFaded() {
703    m_View->SetDupesMode(SHOW_FADED);
704}
705
706void GUIControl::OnShowDupesNormal() {
707    m_View->SetDupesMode(SHOW_NORMAL);
708}
709
710void GUIControl::OnDupesUpdate(wxUpdateUIEvent& cmd) {
711    cmd.Enable(m_View->HasData() && m_View->HasDupes());
712}
713
714void GUIControl::OnHideDupesUpdate(wxUpdateUIEvent& cmd) {
715    cmd.Enable(m_View->HasData() && m_View->HasDupes());
716    cmd.Check(m_View->ShowingDupesMode() == SHOW_HIDE);
717}
718
719void GUIControl::OnShowDupesDashedUpdate(wxUpdateUIEvent& cmd) {
720    cmd.Enable(m_View->HasData() && m_View->HasDupes());
721    cmd.Check(m_View->ShowingDupesMode() == SHOW_DASHED);
722}
723
724void GUIControl::OnShowDupesFadedUpdate(wxUpdateUIEvent& cmd) {
725    cmd.Enable(m_View->HasData() && m_View->HasDupes());
726    cmd.Check(m_View->ShowingDupesMode() == SHOW_FADED);
727}
728
729void GUIControl::OnShowDupesNormalUpdate(wxUpdateUIEvent& cmd) {
730    cmd.Enable(m_View->HasData() && m_View->HasDupes());
731    cmd.Check(m_View->ShowingDupesMode() == SHOW_NORMAL);
732}
733
734void GUIControl::OnMoveEast()
735{
736    m_View->TurnCaveTo(90.0);
737    m_View->ForceRefresh();
738}
739
740void GUIControl::OnMoveEastUpdate(wxUpdateUIEvent& cmd)
741{
742    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 90.0);
743}
744
745void GUIControl::OnMoveNorth()
746{
747    m_View->TurnCaveTo(0.0);
748    m_View->ForceRefresh();
749}
750
751void GUIControl::OnMoveNorthUpdate(wxUpdateUIEvent& cmd)
752{
753    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 0.0);
754}
755
756void GUIControl::OnMoveSouth()
757{
758    m_View->TurnCaveTo(180.0);
759    m_View->ForceRefresh();
760}
761
762void GUIControl::OnMoveSouthUpdate(wxUpdateUIEvent& cmd)
763{
764    cmd.Enable(m_View->HasData() && m_View->GetCompassValue() != 180.0);
765}
766
767void GUIControl::OnMoveWest()
768{
769    m_View->TurnCaveTo(270.0);
770    m_View->ForceRefresh();
771}
772
773void GUIControl::OnMoveWestUpdate(wxUpdateUIEvent& cmd)
774{
775    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && m_View->GetCompassValue() != 270.0);
776}
777
778void GUIControl::OnToggleRotation()
779{
780    m_View->ToggleRotation();
781}
782
783void GUIControl::OnToggleRotationUpdate(wxUpdateUIEvent& cmd)
784{
785    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
786    cmd.Check(m_View->HasData() && m_View->IsRotating());
787}
788
789void GUIControl::OnReverseControls()
790{
791    m_ReverseControls = !m_ReverseControls;
792}
793
794void GUIControl::OnReverseControlsUpdate(wxUpdateUIEvent& cmd)
795{
796    cmd.Enable(m_View->HasData());
797    cmd.Check(m_ReverseControls);
798}
799
800void GUIControl::OnReverseDirectionOfRotation()
801{
802    m_View->ReverseRotation();
803}
804
805void GUIControl::OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent& cmd)
806{
807    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
808}
809
810void GUIControl::OnStepOnceAnticlockwise(bool accel)
811{
812    if (m_View->GetPerspective()) {
813        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
814    } else {
815        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
816    }
817    m_View->ForceRefresh();
818}
819
820void GUIControl::OnStepOnceClockwise(bool accel)
821{
822    if (m_View->GetPerspective()) {
823        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
824    } else {
825        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
826    }
827    m_View->ForceRefresh();
828}
829
830void GUIControl::OnDefaults()
831{
832    m_View->Defaults();
833}
834
835void GUIControl::OnDefaultsUpdate(wxUpdateUIEvent& cmd)
836{
837    cmd.Enable(m_View->HasData());
838}
839
840void GUIControl::OnElevation()
841{
842    // Switch to elevation view.
843
844    m_View->SwitchToElevation();
845}
846
847void GUIControl::OnElevationUpdate(wxUpdateUIEvent& cmd)
848{
849    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingElevation());
850}
851
852void GUIControl::OnHigherViewpoint(bool accel)
853{
854    // Raise the viewpoint.
855    if (m_View->GetPerspective()) {
856        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
857    } else {
858        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
859    }
860    m_View->ForceRefresh();
861}
862
863void GUIControl::OnLowerViewpoint(bool accel)
864{
865    // Lower the viewpoint.
866    if (m_View->GetPerspective()) {
867        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
868    } else {
869        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
870    }
871    m_View->ForceRefresh();
872}
873
874void GUIControl::OnPlan()
875{
876    // Switch to plan view.
877    m_View->SwitchToPlan();
878}
879
880void GUIControl::OnPlanUpdate(wxUpdateUIEvent& cmd)
881{
882    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingPlan());
883}
884
885void GUIControl::OnShiftDisplayDown(bool accel)
886{
887    if (m_View->GetPerspective())
888        m_View->MoveViewer(0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0);
889    else
890        m_View->TranslateCave(0, accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT);
891}
892
893void GUIControl::OnShiftDisplayLeft(bool accel)
894{
895    if (m_View->GetPerspective())
896        m_View->MoveViewer(0, 0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT);
897    else
898        m_View->TranslateCave(accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT, 0);
899}
900
901void GUIControl::OnShiftDisplayRight(bool accel)
902{
903    if (m_View->GetPerspective())
904        m_View->MoveViewer(0, 0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT);
905    else
906        m_View->TranslateCave(accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT, 0);
907}
908
909void GUIControl::OnShiftDisplayUp(bool accel)
910{
911    if (m_View->GetPerspective())
912        m_View->MoveViewer(0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0);
913    else
914        m_View->TranslateCave(0, accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT);
915}
916
917void GUIControl::OnZoomIn(bool accel)
918{
919    // Increase the scale.
920
921    if (m_View->GetPerspective()) {
922        m_View->MoveViewer(accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0, 0);
923    } else {
924        m_View->SetScale(m_View->GetScale() * (accel ? 1.1236 : 1.06));
925        m_View->ForceRefresh();
926    }
927}
928
929void GUIControl::OnZoomOut(bool accel)
930{
931    // Decrease the scale.
932
933    if (m_View->GetPerspective()) {
934        m_View->MoveViewer(accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0, 0);
935    } else {
936        m_View->SetScale(m_View->GetScale() / (accel ? 1.1236 : 1.06));
937        m_View->ForceRefresh();
938    }
939}
940
941void GUIControl::OnToggleScalebar()
942{
943    m_View->ToggleScaleBar();
944}
945
946void GUIControl::OnToggleScalebarUpdate(wxUpdateUIEvent& cmd)
947{
948    cmd.Enable(m_View->HasData());
949    cmd.Check(m_View->ShowingScaleBar());
950}
951
952void GUIControl::OnToggleColourKey()
953{
954    m_View->ToggleColourKey();
955}
956
957void GUIControl::OnToggleColourKeyUpdate(wxUpdateUIEvent& cmd)
958{
959    cmd.Enable(m_View->HasData() && m_View->ColouringBy() != COLOUR_BY_NONE);
960    cmd.Check(m_View->ShowingColourKey());
961}
962
963void GUIControl::OnViewCompass()
964{
965    m_View->ToggleCompass();
966}
967
968void GUIControl::OnViewCompassUpdate(wxUpdateUIEvent& cmd)
969{
970    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
971    cmd.Check(m_View->ShowingCompass());
972}
973
974void GUIControl::OnViewClino()
975{
976    m_View->ToggleClino();
977}
978
979void GUIControl::OnViewClinoUpdate(wxUpdateUIEvent& cmd)
980{
981    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
982    cmd.Check(m_View->ShowingClino());
983}
984
985void GUIControl::OnShowSurface()
986{
987    m_View->ToggleSurfaceLegs();
988}
989
990void GUIControl::OnShowSurfaceUpdate(wxUpdateUIEvent& cmd)
991{
992    cmd.Enable(m_View->HasData() && m_View->HasSurfaceLegs());
993    cmd.Check(m_View->ShowingSurfaceLegs());
994}
995
996void GUIControl::OnShowEntrances()
997{
998    m_View->ToggleEntrances();
999}
1000
1001void GUIControl::OnShowEntrancesUpdate(wxUpdateUIEvent& cmd)
1002{
1003    cmd.Enable(m_View->HasData() && (m_View->GetNumEntrances() > 0));
1004    cmd.Check(m_View->ShowingEntrances());
1005}
1006
1007void GUIControl::OnShowFixedPts()
1008{
1009    m_View->ToggleFixedPts();
1010}
1011
1012void GUIControl::OnShowFixedPtsUpdate(wxUpdateUIEvent& cmd)
1013{
1014    cmd.Enable(m_View->HasData() && (m_View->GetNumFixedPts() > 0));
1015    cmd.Check(m_View->ShowingFixedPts());
1016}
1017
1018void GUIControl::OnShowExportedPts()
1019{
1020    m_View->ToggleExportedPts();
1021}
1022
1023void GUIControl::OnShowExportedPtsUpdate(wxUpdateUIEvent& cmd)
1024{
1025    cmd.Enable(m_View->HasData() && (m_View->GetNumExportedPts() > 0));
1026    cmd.Check(m_View->ShowingExportedPts());
1027}
1028
1029void GUIControl::OnViewGrid()
1030{
1031    m_View->ToggleGrid();
1032}
1033
1034void GUIControl::OnViewGridUpdate(wxUpdateUIEvent& cmd)
1035{
1036    cmd.Enable(m_View->HasData());
1037    cmd.Check(m_View->ShowingGrid());
1038}
1039
1040void GUIControl::OnIndicatorsUpdate(wxUpdateUIEvent& cmd)
1041{
1042    cmd.Enable(m_View->HasData());
1043}
1044
1045void GUIControl::OnViewPerspective()
1046{
1047    m_View->TogglePerspective();
1048    // Force update of coordinate display.
1049    if (m_View->GetPerspective()) {
1050        m_View->MoveViewer(0, 0, 0);
1051    } else {
1052        m_View->ClearCoords();
1053    }
1054}
1055
1056void GUIControl::OnViewPerspectiveUpdate(wxUpdateUIEvent& cmd)
1057{
1058    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
1059    cmd.Check(m_View->GetPerspective());
1060}
1061
1062void GUIControl::OnViewSmoothShading()
1063{
1064    m_View->ToggleSmoothShading();
1065}
1066
1067void GUIControl::OnViewSmoothShadingUpdate(wxUpdateUIEvent& cmd)
1068{
1069    cmd.Enable(m_View->HasData());
1070    cmd.Check(m_View->GetSmoothShading());
1071}
1072
1073void GUIControl::OnViewTextured()
1074{
1075    m_View->ToggleTextured();
1076}
1077
1078void GUIControl::OnViewTexturedUpdate(wxUpdateUIEvent& cmd)
1079{
1080    cmd.Enable(m_View->HasData());
1081    cmd.Check(m_View->GetTextured());
1082}
1083
1084void GUIControl::OnViewFog()
1085{
1086    m_View->ToggleFog();
1087}
1088
1089void GUIControl::OnViewFogUpdate(wxUpdateUIEvent& cmd)
1090{
1091    cmd.Enable(m_View->HasData());
1092    cmd.Check(m_View->GetFog());
1093}
1094
1095void GUIControl::OnViewSmoothLines()
1096{
1097    m_View->ToggleAntiAlias();
1098}
1099
1100void GUIControl::OnViewSmoothLinesUpdate(wxUpdateUIEvent& cmd)
1101{
1102    cmd.Enable(m_View->HasData());
1103    cmd.Check(m_View->GetAntiAlias());
1104}
1105
1106void GUIControl::OnToggleMetric()
1107{
1108    m_View->ToggleMetric();
1109
1110    wxConfigBase::Get()->Write(wxT("metric"), m_View->GetMetric());
1111    wxConfigBase::Get()->Flush();
1112}
1113
1114void GUIControl::OnToggleMetricUpdate(wxUpdateUIEvent& cmd)
1115{
1116    cmd.Enable(m_View->HasData());
1117    cmd.Check(m_View->GetMetric());
1118}
1119
1120void GUIControl::OnToggleDegrees()
1121{
1122    m_View->ToggleDegrees();
1123
1124    wxConfigBase::Get()->Write(wxT("degrees"), m_View->GetDegrees());
1125    wxConfigBase::Get()->Flush();
1126}
1127
1128void GUIControl::OnToggleDegreesUpdate(wxUpdateUIEvent& cmd)
1129{
1130    cmd.Enable(m_View->HasData());
1131    cmd.Check(m_View->GetDegrees());
1132}
1133
1134void GUIControl::OnTogglePercent()
1135{
1136    m_View->TogglePercent();
1137
1138    wxConfigBase::Get()->Write(wxT("percent"), m_View->GetPercent());
1139    wxConfigBase::Get()->Flush();
1140}
1141
1142void GUIControl::OnTogglePercentUpdate(wxUpdateUIEvent& cmd)
1143{
1144    cmd.Enable(m_View->HasData());
1145    cmd.Check(m_View->GetPercent());
1146}
1147
1148void GUIControl::OnToggleTubes()
1149{
1150    m_View->ToggleTubes();
1151}
1152
1153void GUIControl::OnToggleTubesUpdate(wxUpdateUIEvent& cmd)
1154{
1155    cmd.Enable(m_View->HasData() && m_View->HasTubes());
1156    cmd.Check(m_View->GetTubes());
1157}
1158
1159void GUIControl::OnCancelDistLine()
1160{
1161    m_View->ClearTreeSelection();
1162}
1163
1164void GUIControl::OnCancelDistLineUpdate(wxUpdateUIEvent& cmd)
1165{
1166    cmd.Enable(m_View->ShowingMeasuringLine());
1167}
1168
1169void GUIControl::OnKeyPress(wxKeyEvent &e)
1170{
1171    if (!m_View->HasData() ||
1172        (e.GetModifiers() &~ (wxMOD_CONTROL|wxMOD_SHIFT))) {
1173        // Pass on the event if there's no survey data, or if any modifier keys
1174        // other than Ctrl and Shift are pressed.
1175        e.Skip();
1176        return;
1177    }
1178
1179    // The changelog says this is meant to keep animation going while keys are
1180    // pressed, but that happens anyway (on linux at least - perhaps it helps
1181    // on windows?)  FIXME : check!
1182    //bool refresh = m_View->Animate();
1183
1184    switch (e.GetKeyCode()) {
1185        case '/': case '?':
1186            if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
1187                OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1188            break;
1189        case '\'': case '@': case '"': // both shifted forms - US and UK kbd
1190            if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
1191                OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1192            break;
1193        case 'C': case 'c':
1194            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1195                OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
1196            break;
1197        case 'V': case 'v':
1198            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1199                OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
1200            break;
1201        case ']': case '}':
1202            OnZoomIn(e.GetModifiers() == wxMOD_SHIFT);
1203            break;
1204        case '[': case '{':
1205            OnZoomOut(e.GetModifiers() == wxMOD_SHIFT);
1206            break;
1207        case 'N': case 'n':
1208            OnMoveNorth();
1209            break;
1210        case 'S': case 's':
1211            OnMoveSouth();
1212            break;
1213        case 'E': case 'e':
1214            if (!m_View->IsExtendedElevation())
1215                OnMoveEast();
1216            break;
1217        case 'W': case 'w':
1218            if (!m_View->IsExtendedElevation())
1219                OnMoveWest();
1220            break;
1221        case 'Z': case 'z':
1222            if (!m_View->IsExtendedElevation())
1223                m_View->RotateFaster(e.GetModifiers() == wxMOD_SHIFT);
1224            break;
1225        case 'X': case 'x':
1226            if (!m_View->IsExtendedElevation())
1227                m_View->RotateSlower(e.GetModifiers() == wxMOD_SHIFT);
1228            break;
1229        case 'R': case 'r':
1230            if (!m_View->IsExtendedElevation())
1231                OnReverseDirectionOfRotation();
1232            break;
1233        case 'P': case 'p':
1234            if (!m_View->IsExtendedElevation() && !m_View->ShowingPlan())
1235                OnPlan();
1236            break;
1237        case 'L': case 'l':
1238            if (!m_View->IsExtendedElevation() && !m_View->ShowingElevation())
1239                OnElevation();
1240            break;
1241        case 'O': case 'o':
1242            OnDisplayOverlappingNames();
1243            break;
1244        case WXK_DELETE:
1245            if (e.GetModifiers() == 0)
1246                OnDefaults();
1247            break;
1248        case WXK_RETURN:
1249            if (e.GetModifiers() == 0) {
1250                // For compatibility with older versions.
1251                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1252                    m_View->StartRotation();
1253            }
1254            break;
1255        case WXK_SPACE:
1256            if (e.GetModifiers() == 0) {
1257                if (!m_View->IsExtendedElevation())
1258                    OnToggleRotation();
1259            }
1260            break;
1261        case WXK_LEFT:
1262            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1263                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1264                    OnStepOnceAnticlockwise(e.GetModifiers() == wxMOD_SHIFT);
1265            } else {
1266                OnShiftDisplayLeft(e.GetModifiers() == wxMOD_SHIFT);
1267            }
1268            break;
1269        case WXK_RIGHT:
1270            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1271                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
1272                    OnStepOnceClockwise(e.GetModifiers() == wxMOD_SHIFT);
1273            } else {
1274                OnShiftDisplayRight(e.GetModifiers() == wxMOD_SHIFT);
1275            }
1276            break;
1277        case WXK_UP:
1278            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1279                if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
1280                    OnHigherViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1281            } else {
1282                OnShiftDisplayUp(e.GetModifiers() == wxMOD_SHIFT);
1283            }
1284            break;
1285        case WXK_DOWN:
1286            if ((e.GetModifiers() &~ wxMOD_SHIFT) == wxMOD_CONTROL) {
1287                if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
1288                    OnLowerViewpoint(e.GetModifiers() == wxMOD_SHIFT);
1289            } else {
1290                OnShiftDisplayDown(e.GetModifiers() == wxMOD_SHIFT);
1291            }
1292            break;
1293        case WXK_ESCAPE:
1294            if (e.GetModifiers() == 0) {
1295                if (m_View->ShowingMeasuringLine()) {
1296                    OnCancelDistLine();
1297                } else if (m_View->IsFullScreen()) {
1298                    // Cancel full-screen mode on "Escape" if it isn't cancelling
1299                    // the measuring line.
1300                    m_View->FullScreenMode();
1301                }
1302            }
1303            break;
1304        case WXK_F2:
1305            if (e.GetModifiers() == 0)
1306                m_View->ToggleFatFinger();
1307            break;
1308        case WXK_F3:
1309            if (e.GetModifiers() == 0)
1310                m_View->ToggleHitTestDebug();
1311            break;
1312        case WXK_F4: {
1313            if (e.GetModifiers() == 0) {
1314                const wxChar * msg;
1315#if wxDEBUG_LEVEL
1316                if (wxTheAssertHandler)
1317                    wxTheAssertHandler = NULL;
1318                else
1319                    wxSetDefaultAssertHandler();
1320                if (wxTheAssertHandler)
1321                    msg = wxT("Assertions enabled");
1322                else
1323                    msg = wxT("Assertions disabled");
1324#else
1325                msg = wxT("wxWidgets was built without assertions");
1326#endif
1327                wxMessageBox(msg, wxT("Aven Debug"), wxOK | wxICON_INFORMATION);
1328            }
1329            break;
1330        }
1331        case WXK_F5:
1332            if (e.GetModifiers() == 0) {
1333                m_View->InvalidateAllLists();
1334                m_View->ForceRefresh();
1335            }
1336            break;
1337        case WXK_F6:
1338            if (e.GetModifiers() == 0)
1339                m_View->ToggleRenderStats();
1340            break;
1341        default:
1342            e.Skip();
1343    }
1344
1345    //if (refresh) m_View->ForceRefresh();
1346}
1347
1348void GUIControl::OnViewFullScreenUpdate(wxUpdateUIEvent& cmd)
1349{
1350    cmd.Check(m_View->IsFullScreen());
1351}
1352
1353void GUIControl::OnViewFullScreen()
1354{
1355    m_View->FullScreenMode();
1356}
1357
1358void GUIControl::OnViewBoundingBoxUpdate(wxUpdateUIEvent& cmd)
1359{
1360    cmd.Enable(m_View->HasData());
1361    cmd.Check(m_View->DisplayingBoundingBox());
1362}
1363
1364void GUIControl::OnViewBoundingBox()
1365{
1366    m_View->ToggleBoundingBox();
1367}
1368
1369void GUIControl::OnViewTerrainUpdate(wxUpdateUIEvent& cmd)
1370{
1371    cmd.Enable(m_View->HasTerrain());
1372    cmd.Check(m_View->DisplayingTerrain());
1373}
1374
1375void GUIControl::OnViewTerrain()
1376{
1377    m_View->ToggleTerrain();
1378}
Note: See TracBrowser for help on using the repository browser.