~ojwb/survex/master

« back to all changes in this revision

Viewing changes to src/guicontrol.cc

  • Committer: Olly Betts
  • Date: 2010-06-18 07:16:42 UTC
  • mfrom: (2003.1.853)
  • Revision ID: git-v1:75fe355c16c77b1090c4426a3dc0b8dabca31904
Rename branches/survex-1_1 to trunk.

git-svn-id: file:///home/survex-svn/survex/trunk@3454 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 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
 
 
32
const int DISPLAY_SHIFT = 10;
 
33
const double FLYFREE_SHIFT = 0.2;
 
34
const double ROTATE_STEP = 2.0;
 
35
 
 
36
GUIControl::GUIControl()
 
37
    : dragging(NO_DRAG)
 
38
{
 
39
    m_View = NULL;
 
40
    m_ReverseControls = false;
 
41
    m_LastDrag = drag_NONE;
 
42
}
 
43
 
 
44
GUIControl::~GUIControl()
 
45
{
 
46
    // no action
 
47
}
 
48
 
 
49
void GUIControl::SetView(GfxCore* view)
 
50
{
 
51
    m_View = view;
 
52
}
 
53
 
 
54
bool GUIControl::MouseDown() const
 
55
{
 
56
    return (dragging != NO_DRAG);
 
57
}
 
58
 
 
59
void GUIControl::HandleTilt(wxPoint point)
 
60
{
 
61
    // Handle a mouse movement during tilt mode.
 
62
 
 
63
    // wxGTK (at least) fails to update the cursor while dragging.
 
64
    m_View->SetCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
 
65
 
 
66
    int dy = point.y - m_DragStart.y;
 
67
 
 
68
    if (m_ReverseControls != m_View->GetPerspective()) dy = -dy;
 
69
 
 
70
    m_View->TiltCave(Double(-dy) * 0.36);
 
71
 
 
72
    m_DragStart = point;
 
73
 
 
74
    m_View->ForceRefresh();
 
75
}
 
76
 
 
77
void GUIControl::HandleTranslate(wxPoint point)
 
78
{
 
79
    // Handle a mouse movement during translation mode.
 
80
 
 
81
    // wxGTK (at least) fails to update the cursor while dragging.
 
82
    m_View->SetCursor(GfxCore::CURSOR_DRAGGING_HAND);
 
83
 
 
84
    int dx = point.x - m_DragStart.x;
 
85
    int dy = point.y - m_DragStart.y;
 
86
 
 
87
    if (m_ReverseControls) {
 
88
        dx = -dx;
 
89
        dy = -dy;
 
90
    }
 
91
 
 
92
    if (m_View->GetPerspective())
 
93
        m_View->MoveViewer(0, -dy * .1, dx * .1);
 
94
    else
 
95
        m_View->TranslateCave(dx, dy);
 
96
 
 
97
    m_DragStart = point;
 
98
}
 
99
 
 
100
void GUIControl::HandleScaleRotate(wxPoint point)
 
101
{
 
102
    // Handle a mouse movement during scale/rotate mode.
 
103
 
 
104
    // wxGTK (at least) fails to update the cursor while dragging.
 
105
    m_View->SetCursor(GfxCore::CURSOR_ZOOM_ROTATE);
 
106
 
 
107
    int dx, dy;
 
108
    int threshold;
 
109
    if (m_ScaleRotateLock == NONE) {
 
110
        // Dragging to scale or rotate but we've not decided which yet.
 
111
        dx = point.x - m_DragRealStart.x;
 
112
        dy = point.y - m_DragRealStart.y;
 
113
        threshold = 8 * 8;
 
114
    } else {
 
115
        dx = point.x - m_DragStart.x;
 
116
        dy = point.y - m_DragStart.y;
 
117
        threshold = 5;
 
118
    }
 
119
    int dx2 = dx * dx;
 
120
    int dy2 = dy * dy;
 
121
    if (dx2 + dy2 < threshold) return;
 
122
 
 
123
    switch (m_ScaleRotateLock) {
 
124
        case NONE:
 
125
            if (dx2 > dy2) {
 
126
                m_ScaleRotateLock = ROTATE;
 
127
//              m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
 
128
            } else {
 
129
                m_ScaleRotateLock = SCALE;
 
130
//              m_View->SetCursor(GfxCore::CURSOR_ZOOM);
 
131
            }
 
132
            break;
 
133
        case SCALE:
 
134
            if (dx2 >= 8 * dy2) {
 
135
                m_ScaleRotateLock = ROTATE;
 
136
//              m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
 
137
            }
 
138
            break;
 
139
        case ROTATE:
 
140
            if (dy2 >= 8 * dx2) {
 
141
                m_ScaleRotateLock = SCALE;
 
142
//              m_View->SetCursor(GfxCore::CURSOR_ZOOM);
 
143
            }
 
144
            break;
 
145
    }
 
146
 
 
147
    if (m_ScaleRotateLock == ROTATE) {
 
148
        dy = 0;
 
149
    } else {
 
150
        dx = 0;
 
151
    }
 
152
 
 
153
    if (m_ReverseControls) {
 
154
        dx = -dx;
 
155
        dy = -dy;
 
156
    }
 
157
 
 
158
    if (m_View->GetPerspective()) {
 
159
        if (dy) m_View->MoveViewer(-dy * .1, 0, 0);
 
160
    } else {
 
161
        // up/down => scale.
 
162
        if (dy) m_View->SetScale(m_View->GetScale() * pow(1.06, 0.08 * dy));
 
163
        // left/right => rotate.
 
164
        if (dx) m_View->TurnCave(Double(dx) * -0.36);
 
165
        if (dx || dy) m_View->ForceRefresh();
 
166
    }
 
167
 
 
168
    m_DragStart = point;
 
169
}
 
170
 
 
171
void GUIControl::HandleTiltRotate(wxPoint point)
 
172
{
 
173
    // Handle a mouse movement during tilt/rotate mode.
 
174
    if (m_View->IsExtendedElevation()) return;
 
175
 
 
176
    // wxGTK (at least) fails to update the cursor while dragging.
 
177
    m_View->SetCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY);
 
178
 
 
179
    int dx = point.x - m_DragStart.x;
 
180
    int dy = point.y - m_DragStart.y;
 
181
 
 
182
    if (m_ReverseControls != m_View->GetPerspective()) {
 
183
        dx = -dx;
 
184
        dy = -dy;
 
185
    }
 
186
 
 
187
    // left/right => rotate, up/down => tilt.
 
188
    // Make tilt less sensitive than rotate as that feels better.
 
189
    m_View->TurnCave(Double(dx) * -0.36);
 
190
    m_View->TiltCave(Double(dy) * -0.18);
 
191
 
 
192
    m_View->ForceRefresh();
 
193
 
 
194
    m_DragStart = point;
 
195
}
 
196
 
 
197
void GUIControl::HandleRotate(wxPoint point)
 
198
{
 
199
    // Handle a mouse movement during rotate mode.
 
200
    if (m_View->IsExtendedElevation()) return;
 
201
 
 
202
    // wxGTK (at least) fails to update the cursor while dragging.
 
203
    m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
 
204
 
 
205
    int dx = point.x - m_DragStart.x;
 
206
    int dy = point.y - m_DragStart.y;
 
207
 
 
208
    if (m_ReverseControls != m_View->GetPerspective()) {
 
209
        dx = -dx;
 
210
        dy = -dy;
 
211
    }
 
212
 
 
213
    // left/right => rotate.
 
214
    m_View->TurnCave(Double(dx) * -0.36);
 
215
 
 
216
    m_View->ForceRefresh();
 
217
 
 
218
    m_DragStart = point;
 
219
}
 
220
 
 
221
void GUIControl::RestoreCursor()
 
222
{
 
223
    if (m_View->HereIsReal()) {
 
224
        m_View->SetCursor(GfxCore::CURSOR_POINTING_HAND);
 
225
    } else {
 
226
        m_View->SetCursor(GfxCore::CURSOR_DEFAULT);
 
227
    }
 
228
}
 
229
 
 
230
void GUIControl::HandleNonDrag(const wxPoint & point) {
 
231
    if (m_View->CheckHitTestGrid(point, false)) {
 
232
        m_View->SetCursor(GfxCore::CURSOR_POINTING_HAND);
 
233
    } else if (m_View->PointWithinScaleBar(point)) {
 
234
        m_View->SetCursor(GfxCore::CURSOR_HORIZONTAL_RESIZE);
 
235
    } else if (m_View->PointWithinCompass(point)) {
 
236
        m_View->SetCursor(GfxCore::CURSOR_ROTATE_HORIZONTALLY);
 
237
    } else if (m_View->PointWithinClino(point)) {
 
238
        m_View->SetCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
 
239
    } else {
 
240
        RestoreCursor();
 
241
    }
 
242
}
 
243
 
 
244
//
 
245
//  Mouse event handling methods
 
246
//
 
247
 
 
248
void GUIControl::OnMouseMove(wxMouseEvent& event)
 
249
{
 
250
    // Mouse motion event handler.
 
251
    if (!m_View->HasData()) return;
 
252
 
 
253
    // Ignore moves which don't change the position.
 
254
    if (event.GetPosition() == m_DragStart) {
 
255
        return;
 
256
    }
 
257
 
 
258
    static long timestamp = LONG_MIN;
 
259
    if (dragging != NO_DRAG && m_ScaleRotateLock != NONE && timestamp != LONG_MIN) {
 
260
        // If no motion for a second, reset the direction lock.
 
261
        if (event.GetTimestamp() - timestamp >= 1000) {
 
262
            m_ScaleRotateLock = NONE;
 
263
            m_DragRealStart = m_DragStart;
 
264
            RestoreCursor();
 
265
        }
 
266
    }
 
267
    timestamp = event.GetTimestamp();
 
268
 
 
269
    wxPoint point(event.GetPosition());
 
270
 
 
271
    // Check hit-test grid (only if no buttons are pressed).
 
272
    if (!event.LeftIsDown() && !event.MiddleIsDown() && !event.RightIsDown()) {
 
273
        HandleNonDrag(point);
 
274
    }
 
275
 
 
276
    // Update coordinate display if in plan view,
 
277
    // or altitude if in elevation view.
 
278
    m_View->SetCoords(point);
 
279
 
 
280
    switch (dragging) {
 
281
        case LEFT_DRAG:
 
282
            switch (m_LastDrag) {
 
283
                case drag_COMPASS:
 
284
                    // Drag in heading indicator.
 
285
                    m_View->SetCompassFromPoint(point);
 
286
                    break;
 
287
                case drag_ELEV:
 
288
                    // Drag in clinometer.
 
289
                    m_View->SetClinoFromPoint(point);
 
290
                    break;
 
291
                case drag_SCALE:
 
292
                    m_View->SetScaleBarFromOffset(point.x - m_DragLast.x);
 
293
                    break;
 
294
                case drag_MAIN:
 
295
                    if (event.ControlDown()) {
 
296
                        HandleTiltRotate(point);
 
297
                    } else {
 
298
                        HandleScaleRotate(point);
 
299
                    }
 
300
                    break;
 
301
                case drag_NONE:
 
302
                    // Shouldn't happen?!  FIXME: assert or something.
 
303
                    break;
 
304
            }
 
305
            break;
 
306
        case MIDDLE_DRAG:
 
307
            HandleTilt(point);
 
308
            break;
 
309
        case RIGHT_DRAG:
 
310
            HandleTranslate(point);
 
311
            break;
 
312
        case NO_DRAG:
 
313
            break;
 
314
    }
 
315
 
 
316
    m_DragLast = point;
 
317
}
 
318
 
 
319
void GUIControl::OnLButtonDown(wxMouseEvent& event)
 
320
{
 
321
    if (m_View->HasData()) {
 
322
        dragging = LEFT_DRAG;
 
323
 
 
324
        m_DragStart = m_DragRealStart = event.GetPosition();
 
325
 
 
326
        if (m_View->PointWithinCompass(m_DragStart)) {
 
327
            m_LastDrag = drag_COMPASS;
 
328
        } else if (m_View->PointWithinClino(m_DragStart)) {
 
329
            m_LastDrag = drag_ELEV;
 
330
        } else if (m_View->PointWithinScaleBar(m_DragStart)) {
 
331
            m_LastDrag = drag_SCALE;
 
332
        } else {
 
333
            if (event.ControlDown()) {
 
334
                if (m_View->IsExtendedElevation()) {
 
335
                    dragging = NO_DRAG;
 
336
                    return;
 
337
                }
 
338
                m_View->SetCursor(GfxCore::CURSOR_ROTATE_EITHER_WAY);
 
339
            } else {
 
340
                m_View->SetCursor(GfxCore::CURSOR_ZOOM_ROTATE);
 
341
            }
 
342
 
 
343
            m_LastDrag = drag_MAIN;
 
344
            m_ScaleRotateLock = NONE;
 
345
        }
 
346
 
 
347
        m_View->CaptureMouse();
 
348
    }
 
349
}
 
350
 
 
351
void GUIControl::OnLButtonUp(wxMouseEvent& event)
 
352
{
 
353
    if (m_View->HasData()) {
 
354
        if (event.GetPosition() == m_DragRealStart) {
 
355
            // Just a "click"...
 
356
            m_View->CheckHitTestGrid(m_DragStart, true);
 
357
        } else if (dragging == NO_DRAG) {
 
358
            return;
 
359
        }
 
360
 
 
361
//      m_View->RedrawIndicators();
 
362
        m_View->ReleaseMouse();
 
363
 
 
364
        m_LastDrag = drag_NONE;
 
365
        dragging = NO_DRAG;
 
366
 
 
367
        m_View->DragFinished();
 
368
 
 
369
        if (event.GetPosition() == m_DragRealStart) {
 
370
            RestoreCursor();
 
371
        } else {
 
372
            HandleNonDrag(event.GetPosition());
 
373
        }
 
374
    }
 
375
}
 
376
 
 
377
void GUIControl::OnMButtonDown(wxMouseEvent& event)
 
378
{
 
379
    if (m_View->HasData() && !m_View->IsExtendedElevation()) {
 
380
        dragging = MIDDLE_DRAG;
 
381
        m_DragStart = event.GetPosition();
 
382
 
 
383
        m_View->SetCursor(GfxCore::CURSOR_ROTATE_VERTICALLY);
 
384
 
 
385
        m_View->CaptureMouse();
 
386
    }
 
387
}
 
388
 
 
389
void GUIControl::OnMButtonUp(wxMouseEvent&)
 
390
{
 
391
    if (m_View->HasData()) {
 
392
        dragging = NO_DRAG;
 
393
        m_View->ReleaseMouse();
 
394
        m_View->DragFinished();
 
395
 
 
396
        RestoreCursor();
 
397
    }
 
398
}
 
399
 
 
400
void GUIControl::OnRButtonDown(wxMouseEvent& event)
 
401
{
 
402
    if (m_View->HasData()) {
 
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
 
 
412
void 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
 
 
424
void 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
 
 
434
void GUIControl::OnDisplayOverlappingNames()
 
435
{
 
436
    m_View->ToggleOverlappingNames();
 
437
}
 
438
 
 
439
void GUIControl::OnDisplayOverlappingNamesUpdate(wxUpdateUIEvent& cmd)
 
440
{
 
441
    cmd.Enable(m_View->HasData() && m_View->ShowingStationNames());
 
442
    cmd.Check(m_View->ShowingOverlappingNames());
 
443
}
 
444
 
 
445
void 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
 
 
454
void 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
 
 
463
void 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
 
 
472
void GUIControl::OnColourByDepthUpdate(wxUpdateUIEvent& cmd)
 
473
{
 
474
    cmd.Enable(m_View->HasData() && !m_View->HasDepth());
 
475
    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DEPTH);
 
476
}
 
477
 
 
478
void GUIControl::OnColourByDateUpdate(wxUpdateUIEvent& cmd)
 
479
{
 
480
    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs() && m_View->HasRangeOfDates());
 
481
    cmd.Check(m_View->ColouringBy() == COLOUR_BY_DATE);
 
482
}
 
483
 
 
484
void GUIControl::OnColourByErrorUpdate(wxUpdateUIEvent& cmd)
 
485
{
 
486
    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs() && m_View->HasErrorInformation());
 
487
    cmd.Check(m_View->ColouringBy() == COLOUR_BY_ERROR);
 
488
}
 
489
 
 
490
void GUIControl::OnShowCrosses()
 
491
{
 
492
    m_View->ToggleCrosses();
 
493
}
 
494
 
 
495
void GUIControl::OnShowCrossesUpdate(wxUpdateUIEvent& cmd)
 
496
{
 
497
    cmd.Enable(m_View->HasData());
 
498
    cmd.Check(m_View->ShowingCrosses());
 
499
}
 
500
 
 
501
void GUIControl::OnShowStationNames()
 
502
{
 
503
    m_View->ToggleStationNames();
 
504
}
 
505
 
 
506
void GUIControl::OnShowStationNamesUpdate(wxUpdateUIEvent& cmd)
 
507
{
 
508
    cmd.Enable(m_View->HasData());
 
509
    cmd.Check(m_View->ShowingStationNames());
 
510
}
 
511
 
 
512
void GUIControl::OnShowSurveyLegs()
 
513
{
 
514
    m_View->ToggleUndergroundLegs();
 
515
}
 
516
 
 
517
void GUIControl::OnShowSurveyLegsUpdate(wxUpdateUIEvent& cmd)
 
518
{
 
519
    cmd.Enable(m_View->HasData() && m_View->HasUndergroundLegs());
 
520
    cmd.Check(m_View->ShowingUndergroundLegs());
 
521
}
 
522
 
 
523
void GUIControl::OnMoveEast()
 
524
{
 
525
    m_View->TurnCaveTo(90.0);
 
526
    m_View->ForceRefresh();
 
527
}
 
528
 
 
529
void GUIControl::OnMoveEastUpdate(wxUpdateUIEvent& cmd)
 
530
{
 
531
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
532
}
 
533
 
 
534
void GUIControl::OnMoveNorth()
 
535
{
 
536
    m_View->TurnCaveTo(0.0);
 
537
    m_View->ForceRefresh();
 
538
}
 
539
 
 
540
void GUIControl::OnMoveNorthUpdate(wxUpdateUIEvent& cmd)
 
541
{
 
542
    cmd.Enable(m_View->HasData());
 
543
}
 
544
 
 
545
void GUIControl::OnMoveSouth()
 
546
{
 
547
    m_View->TurnCaveTo(180.0);
 
548
    m_View->ForceRefresh();
 
549
}
 
550
 
 
551
void GUIControl::OnMoveSouthUpdate(wxUpdateUIEvent& cmd)
 
552
{
 
553
    cmd.Enable(m_View->HasData());
 
554
}
 
555
 
 
556
void GUIControl::OnMoveWest()
 
557
{
 
558
    m_View->TurnCaveTo(270.0);
 
559
    m_View->ForceRefresh();
 
560
}
 
561
 
 
562
void GUIControl::OnMoveWestUpdate(wxUpdateUIEvent& cmd)
 
563
{
 
564
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
565
}
 
566
 
 
567
void GUIControl::OnToggleRotation()
 
568
{
 
569
    m_View->ToggleRotation();
 
570
}
 
571
 
 
572
void GUIControl::OnToggleRotationUpdate(wxUpdateUIEvent& cmd)
 
573
{
 
574
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
575
    cmd.Check(m_View->HasData() && m_View->IsRotating());
 
576
}
 
577
 
 
578
void GUIControl::OnReverseControls()
 
579
{
 
580
    m_ReverseControls = !m_ReverseControls;
 
581
}
 
582
 
 
583
void GUIControl::OnReverseControlsUpdate(wxUpdateUIEvent& cmd)
 
584
{
 
585
    cmd.Enable(m_View->HasData());
 
586
    cmd.Check(m_ReverseControls);
 
587
}
 
588
 
 
589
void GUIControl::OnReverseDirectionOfRotation()
 
590
{
 
591
    m_View->ReverseRotation();
 
592
}
 
593
 
 
594
void GUIControl::OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent& cmd)
 
595
{
 
596
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
597
}
 
598
 
 
599
void GUIControl::OnSlowDown(bool accel)
 
600
{
 
601
    m_View->RotateSlower(accel);
 
602
}
 
603
 
 
604
void GUIControl::OnSlowDownUpdate(wxUpdateUIEvent& cmd)
 
605
{
 
606
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
607
}
 
608
 
 
609
void GUIControl::OnSpeedUp(bool accel)
 
610
{
 
611
    m_View->RotateFaster(accel);
 
612
}
 
613
 
 
614
void GUIControl::OnSpeedUpUpdate(wxUpdateUIEvent& cmd)
 
615
{
 
616
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
617
}
 
618
 
 
619
void GUIControl::OnStepOnceAnticlockwise(bool accel)
 
620
{
 
621
    if (m_View->GetPerspective()) {
 
622
        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
 
623
    } else {
 
624
        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
 
625
    }
 
626
    m_View->ForceRefresh();
 
627
}
 
628
 
 
629
void GUIControl::OnStepOnceAnticlockwiseUpdate(wxUpdateUIEvent& cmd)
 
630
{
 
631
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->IsRotating());
 
632
}
 
633
 
 
634
void GUIControl::OnStepOnceClockwise(bool accel)
 
635
{
 
636
    if (m_View->GetPerspective()) {
 
637
        m_View->TurnCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
 
638
    } else {
 
639
        m_View->TurnCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
 
640
    }
 
641
    m_View->ForceRefresh();
 
642
}
 
643
 
 
644
void GUIControl::OnStepOnceClockwiseUpdate(wxUpdateUIEvent& cmd)
 
645
{
 
646
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->IsRotating());
 
647
}
 
648
 
 
649
void GUIControl::OnDefaults()
 
650
{
 
651
    m_View->Defaults();
 
652
}
 
653
 
 
654
void GUIControl::OnDefaultsUpdate(wxUpdateUIEvent& cmd)
 
655
{
 
656
    cmd.Enable(m_View->HasData());
 
657
}
 
658
 
 
659
void GUIControl::OnElevation()
 
660
{
 
661
    // Switch to elevation view.
 
662
 
 
663
    m_View->SwitchToElevation();
 
664
}
 
665
 
 
666
void GUIControl::OnElevationUpdate(wxUpdateUIEvent& cmd)
 
667
{
 
668
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingElevation());
 
669
}
 
670
 
 
671
void GUIControl::OnHigherViewpoint(bool accel)
 
672
{
 
673
    // Raise the viewpoint.
 
674
    if (m_View->GetPerspective()) {
 
675
        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
 
676
    } else {
 
677
        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
 
678
    }
 
679
    m_View->ForceRefresh();
 
680
}
 
681
 
 
682
void GUIControl::OnHigherViewpointUpdate(wxUpdateUIEvent& cmd)
 
683
{
 
684
    cmd.Enable(m_View->HasData() && m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation());
 
685
}
 
686
 
 
687
void GUIControl::OnLowerViewpoint(bool accel)
 
688
{
 
689
    // Lower the viewpoint.
 
690
    if (m_View->GetPerspective()) {
 
691
        m_View->TiltCave(accel ? 5.0 * ROTATE_STEP : ROTATE_STEP);
 
692
    } else {
 
693
        m_View->TiltCave(accel ? -5.0 * ROTATE_STEP : -ROTATE_STEP);
 
694
    }
 
695
    m_View->ForceRefresh();
 
696
}
 
697
 
 
698
void GUIControl::OnLowerViewpointUpdate(wxUpdateUIEvent& cmd)
 
699
{
 
700
    cmd.Enable(m_View->HasData() && m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation());
 
701
}
 
702
 
 
703
void GUIControl::OnPlan()
 
704
{
 
705
    // Switch to plan view.
 
706
    m_View->SwitchToPlan();
 
707
}
 
708
 
 
709
void GUIControl::OnPlanUpdate(wxUpdateUIEvent& cmd)
 
710
{
 
711
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation() && !m_View->ShowingPlan());
 
712
}
 
713
 
 
714
void GUIControl::OnShiftDisplayDown(bool accel)
 
715
{
 
716
    if (m_View->GetPerspective())
 
717
        m_View->MoveViewer(0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0);
 
718
    else
 
719
        m_View->TranslateCave(0, accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT);
 
720
}
 
721
 
 
722
void GUIControl::OnShiftDisplayDownUpdate(wxUpdateUIEvent& cmd)
 
723
{
 
724
    cmd.Enable(m_View->HasData());
 
725
}
 
726
 
 
727
void GUIControl::OnShiftDisplayLeft(bool accel)
 
728
{
 
729
    if (m_View->GetPerspective())
 
730
        m_View->MoveViewer(0, 0, accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT);
 
731
    else
 
732
        m_View->TranslateCave(accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT, 0);
 
733
}
 
734
 
 
735
void GUIControl::OnShiftDisplayLeftUpdate(wxUpdateUIEvent& cmd)
 
736
{
 
737
    cmd.Enable(m_View->HasData());
 
738
}
 
739
 
 
740
void GUIControl::OnShiftDisplayRight(bool accel)
 
741
{
 
742
    if (m_View->GetPerspective())
 
743
        m_View->MoveViewer(0, 0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT);
 
744
    else
 
745
        m_View->TranslateCave(accel ? 5 * DISPLAY_SHIFT : DISPLAY_SHIFT, 0);
 
746
}
 
747
 
 
748
void GUIControl::OnShiftDisplayRightUpdate(wxUpdateUIEvent& cmd)
 
749
{
 
750
    cmd.Enable(m_View->HasData());
 
751
}
 
752
 
 
753
void GUIControl::OnShiftDisplayUp(bool accel)
 
754
{
 
755
    if (m_View->GetPerspective())
 
756
        m_View->MoveViewer(0, accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0);
 
757
    else
 
758
        m_View->TranslateCave(0, accel ? -5 * DISPLAY_SHIFT : -DISPLAY_SHIFT);
 
759
}
 
760
 
 
761
void GUIControl::OnShiftDisplayUpUpdate(wxUpdateUIEvent& cmd)
 
762
{
 
763
    cmd.Enable(m_View->HasData());
 
764
}
 
765
 
 
766
void GUIControl::OnZoomIn(bool accel)
 
767
{
 
768
    // Increase the scale.
 
769
 
 
770
    if (m_View->GetPerspective()) {
 
771
        m_View->MoveViewer(accel ? 5 * FLYFREE_SHIFT : FLYFREE_SHIFT, 0, 0);
 
772
    } else {
 
773
        m_View->SetScale(m_View->GetScale() * (accel ? 1.1236 : 1.06));
 
774
        m_View->ForceRefresh();
 
775
    }
 
776
}
 
777
 
 
778
void GUIControl::OnZoomInUpdate(wxUpdateUIEvent& cmd)
 
779
{
 
780
    cmd.Enable(m_View->HasData());
 
781
}
 
782
 
 
783
void GUIControl::OnZoomOut(bool accel)
 
784
{
 
785
    // Decrease the scale.
 
786
 
 
787
    if (m_View->GetPerspective()) {
 
788
        m_View->MoveViewer(accel ? -5 * FLYFREE_SHIFT : -FLYFREE_SHIFT, 0, 0);
 
789
    } else {
 
790
        m_View->SetScale(m_View->GetScale() / (accel ? 1.1236 : 1.06));
 
791
        m_View->ForceRefresh();
 
792
    }
 
793
}
 
794
 
 
795
void GUIControl::OnZoomOutUpdate(wxUpdateUIEvent& cmd)
 
796
{
 
797
    cmd.Enable(m_View->HasData());
 
798
}
 
799
 
 
800
void GUIControl::OnToggleScalebar()
 
801
{
 
802
    m_View->ToggleScaleBar();
 
803
}
 
804
 
 
805
void GUIControl::OnToggleScalebarUpdate(wxUpdateUIEvent& cmd)
 
806
{
 
807
    cmd.Enable(m_View->HasData());
 
808
    cmd.Check(m_View->ShowingScaleBar());
 
809
}
 
810
 
 
811
void GUIControl::OnToggleDepthbar() /* FIXME naming */
 
812
{
 
813
    m_View->ToggleDepthBar();
 
814
}
 
815
 
 
816
void GUIControl::OnToggleDepthbarUpdate(wxUpdateUIEvent& cmd)
 
817
{
 
818
    cmd.Enable(m_View->HasData() && m_View->ColouringBy() == COLOUR_BY_DEPTH);
 
819
    cmd.Check(m_View->ShowingDepthBar());
 
820
}
 
821
 
 
822
void GUIControl::OnViewCompass()
 
823
{
 
824
    m_View->ToggleCompass();
 
825
}
 
826
 
 
827
void GUIControl::OnViewCompassUpdate(wxUpdateUIEvent& cmd)
 
828
{
 
829
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
830
    cmd.Check(m_View->ShowingCompass());
 
831
}
 
832
 
 
833
void GUIControl::OnViewClino()
 
834
{
 
835
    m_View->ToggleClino();
 
836
}
 
837
 
 
838
void GUIControl::OnViewClinoUpdate(wxUpdateUIEvent& cmd)
 
839
{
 
840
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
841
    cmd.Check(m_View->ShowingClino());
 
842
}
 
843
 
 
844
void GUIControl::OnShowSurface()
 
845
{
 
846
    m_View->ToggleSurfaceLegs();
 
847
}
 
848
 
 
849
void GUIControl::OnShowSurfaceUpdate(wxUpdateUIEvent& cmd)
 
850
{
 
851
    cmd.Enable(m_View->HasData() && m_View->HasSurfaceLegs());
 
852
    cmd.Check(m_View->ShowingSurfaceLegs());
 
853
}
 
854
 
 
855
void GUIControl::OnShowEntrances()
 
856
{
 
857
    m_View->ToggleEntrances();
 
858
}
 
859
 
 
860
void GUIControl::OnShowEntrancesUpdate(wxUpdateUIEvent& cmd)
 
861
{
 
862
    cmd.Enable(m_View->HasData() && (m_View->GetNumEntrances() > 0));
 
863
    cmd.Check(m_View->ShowingEntrances());
 
864
}
 
865
 
 
866
void GUIControl::OnShowFixedPts()
 
867
{
 
868
    m_View->ToggleFixedPts();
 
869
}
 
870
 
 
871
void GUIControl::OnShowFixedPtsUpdate(wxUpdateUIEvent& cmd)
 
872
{
 
873
    cmd.Enable(m_View->HasData() && (m_View->GetNumFixedPts() > 0));
 
874
    cmd.Check(m_View->ShowingFixedPts());
 
875
}
 
876
 
 
877
void GUIControl::OnShowExportedPts()
 
878
{
 
879
    m_View->ToggleExportedPts();
 
880
}
 
881
 
 
882
void GUIControl::OnShowExportedPtsUpdate(wxUpdateUIEvent& cmd)
 
883
{
 
884
    cmd.Enable(m_View->HasData() && (m_View->GetNumExportedPts() > 0));
 
885
    cmd.Check(m_View->ShowingExportedPts());
 
886
}
 
887
 
 
888
void GUIControl::OnViewGrid()
 
889
{
 
890
    m_View->ToggleGrid();
 
891
}
 
892
 
 
893
void GUIControl::OnViewGridUpdate(wxUpdateUIEvent& cmd)
 
894
{
 
895
    cmd.Enable(m_View->HasData());
 
896
    cmd.Check(m_View->ShowingGrid());
 
897
}
 
898
 
 
899
void GUIControl::OnIndicatorsUpdate(wxUpdateUIEvent& cmd)
 
900
{
 
901
    cmd.Enable(m_View->HasData());
 
902
}
 
903
 
 
904
void GUIControl::OnViewPerspective()
 
905
{
 
906
    m_View->TogglePerspective();
 
907
    // Force update of coordinate display.
 
908
    if (m_View->GetPerspective()) {
 
909
        m_View->MoveViewer(0, 0, 0);
 
910
    } else {
 
911
        m_View->ClearCoords();
 
912
    }
 
913
}
 
914
 
 
915
void GUIControl::OnViewPerspectiveUpdate(wxUpdateUIEvent& cmd)
 
916
{
 
917
    cmd.Enable(m_View->HasData() && !m_View->IsExtendedElevation());
 
918
    cmd.Check(m_View->GetPerspective());
 
919
}
 
920
 
 
921
void GUIControl::OnViewSmoothShading()
 
922
{
 
923
    m_View->ToggleSmoothShading();
 
924
}
 
925
 
 
926
void GUIControl::OnViewSmoothShadingUpdate(wxUpdateUIEvent& cmd)
 
927
{
 
928
    cmd.Enable(m_View->HasData());
 
929
    cmd.Check(m_View->GetSmoothShading());
 
930
}
 
931
 
 
932
void GUIControl::OnViewTextured()
 
933
{
 
934
    m_View->ToggleTextured();
 
935
}
 
936
 
 
937
void GUIControl::OnViewTexturedUpdate(wxUpdateUIEvent& cmd)
 
938
{
 
939
    cmd.Enable(m_View->HasData());
 
940
    cmd.Check(m_View->GetTextured());
 
941
}
 
942
 
 
943
void GUIControl::OnViewFog()
 
944
{
 
945
    m_View->ToggleFog();
 
946
}
 
947
 
 
948
void GUIControl::OnViewFogUpdate(wxUpdateUIEvent& cmd)
 
949
{
 
950
    cmd.Enable(m_View->HasData());
 
951
    cmd.Check(m_View->GetFog());
 
952
}
 
953
 
 
954
void GUIControl::OnViewSmoothLines()
 
955
{
 
956
    m_View->ToggleAntiAlias();
 
957
}
 
958
 
 
959
void GUIControl::OnViewSmoothLinesUpdate(wxUpdateUIEvent& cmd)
 
960
{
 
961
    cmd.Enable(m_View->HasData());
 
962
    cmd.Check(m_View->GetAntiAlias());
 
963
}
 
964
 
 
965
void GUIControl::OnToggleMetric()
 
966
{
 
967
    m_View->ToggleMetric();
 
968
 
 
969
    wxConfigBase::Get()->Write(wxT("metric"), m_View->GetMetric());
 
970
    wxConfigBase::Get()->Flush();
 
971
}
 
972
 
 
973
void GUIControl::OnToggleMetricUpdate(wxUpdateUIEvent& cmd)
 
974
{
 
975
    cmd.Enable(m_View->HasData());
 
976
    cmd.Check(m_View->GetMetric());
 
977
}
 
978
 
 
979
void GUIControl::OnToggleDegrees()
 
980
{
 
981
    m_View->ToggleDegrees();
 
982
 
 
983
    wxConfigBase::Get()->Write(wxT("degrees"), m_View->GetDegrees());
 
984
    wxConfigBase::Get()->Flush();
 
985
}
 
986
 
 
987
void GUIControl::OnToggleDegreesUpdate(wxUpdateUIEvent& cmd)
 
988
{
 
989
    cmd.Enable(m_View->HasData());
 
990
    cmd.Check(m_View->GetDegrees());
 
991
}
 
992
 
 
993
void GUIControl::OnToggleTubes()
 
994
{
 
995
    m_View->ToggleTubes();
 
996
}
 
997
 
 
998
void GUIControl::OnToggleTubesUpdate(wxUpdateUIEvent& cmd)
 
999
{
 
1000
    cmd.Enable(m_View->HasData() && m_View->HasTubes());
 
1001
    cmd.Check(m_View->GetTubes());
 
1002
}
 
1003
 
 
1004
void GUIControl::OnCancelDistLine()
 
1005
{
 
1006
    m_View->ClearTreeSelection();
 
1007
}
 
1008
 
 
1009
void GUIControl::OnCancelDistLineUpdate(wxUpdateUIEvent& cmd)
 
1010
{
 
1011
    cmd.Enable(m_View->ShowingMeasuringLine());
 
1012
}
 
1013
 
 
1014
void GUIControl::OnKeyPress(wxKeyEvent &e)
 
1015
{
 
1016
    if (!m_View->HasData()) {
 
1017
        e.Skip();
 
1018
        return;
 
1019
    }
 
1020
 
 
1021
    // The changelog says this is meant to keep animation going while keys are
 
1022
    // pressed, but that happens anyway (on linux at least - perhaps it helps
 
1023
    // on windows?)  FIXME : check!
 
1024
    //bool refresh = m_View->Animate();
 
1025
 
 
1026
    switch (e.m_keyCode) {
 
1027
        case '/': case '?':
 
1028
            if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
 
1029
                OnLowerViewpoint(e.m_shiftDown);
 
1030
            break;
 
1031
        case '\'': case '@': case '"': // both shifted forms - US and UK kbd
 
1032
            if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
 
1033
                OnHigherViewpoint(e.m_shiftDown);
 
1034
            break;
 
1035
        case 'C': case 'c':
 
1036
            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
 
1037
                OnStepOnceAnticlockwise(e.m_shiftDown);
 
1038
            break;
 
1039
        case 'V': case 'v':
 
1040
            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
 
1041
                OnStepOnceClockwise(e.m_shiftDown);
 
1042
            break;
 
1043
        case ']': case '}':
 
1044
            OnZoomIn(e.m_shiftDown);
 
1045
            break;
 
1046
        case '[': case '{':
 
1047
            OnZoomOut(e.m_shiftDown);
 
1048
            break;
 
1049
        case 'N': case 'n':
 
1050
            OnMoveNorth();
 
1051
            break;
 
1052
        case 'S': case 's':
 
1053
            OnMoveSouth();
 
1054
            break;
 
1055
        case 'E': case 'e':
 
1056
            if (!m_View->IsExtendedElevation())
 
1057
                OnMoveEast();
 
1058
            break;
 
1059
        case 'W': case 'w':
 
1060
            if (!m_View->IsExtendedElevation())
 
1061
                OnMoveWest();
 
1062
            break;
 
1063
        case 'Z': case 'z':
 
1064
            if (!m_View->IsExtendedElevation())
 
1065
                OnSpeedUp(e.m_shiftDown);
 
1066
            break;
 
1067
        case 'X': case 'x':
 
1068
            if (!m_View->IsExtendedElevation())
 
1069
                OnSlowDown(e.m_shiftDown);
 
1070
            break;
 
1071
        case 'R': case 'r':
 
1072
            if (!m_View->IsExtendedElevation())
 
1073
                OnReverseDirectionOfRotation();
 
1074
            break;
 
1075
        case 'P': case 'p':
 
1076
            if (!m_View->IsExtendedElevation() && !m_View->ShowingPlan())
 
1077
                OnPlan();
 
1078
            break;
 
1079
        case 'L': case 'l':
 
1080
            if (!m_View->IsExtendedElevation() && !m_View->ShowingElevation())
 
1081
                OnElevation();
 
1082
            break;
 
1083
        case 'O': case 'o':
 
1084
            OnDisplayOverlappingNames();
 
1085
            break;
 
1086
        case WXK_DELETE:
 
1087
            OnDefaults();
 
1088
            break;
 
1089
        case WXK_RETURN:
 
1090
            // For compatibility with older versions.
 
1091
            if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
 
1092
                m_View->StartRotation();
 
1093
            break;
 
1094
        case WXK_SPACE:
 
1095
            if (!m_View->IsExtendedElevation())
 
1096
                OnToggleRotation();
 
1097
            break;
 
1098
        case WXK_LEFT:
 
1099
            if (e.m_controlDown) {
 
1100
                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
 
1101
                    OnStepOnceAnticlockwise(e.m_shiftDown);
 
1102
            } else {
 
1103
                OnShiftDisplayLeft(e.m_shiftDown);
 
1104
            }
 
1105
            break;
 
1106
        case WXK_RIGHT:
 
1107
            if (e.m_controlDown) {
 
1108
                if (!m_View->IsExtendedElevation() && !m_View->IsRotating())
 
1109
                    OnStepOnceClockwise(e.m_shiftDown);
 
1110
            } else {
 
1111
                OnShiftDisplayRight(e.m_shiftDown);
 
1112
            }
 
1113
            break;
 
1114
        case WXK_UP:
 
1115
            if (e.m_controlDown) {
 
1116
                if (m_View->CanRaiseViewpoint() && !m_View->IsExtendedElevation())
 
1117
                    OnHigherViewpoint(e.m_shiftDown);
 
1118
            } else {
 
1119
                OnShiftDisplayUp(e.m_shiftDown);
 
1120
            }
 
1121
            break;
 
1122
        case WXK_DOWN:
 
1123
            if (e.m_controlDown) {
 
1124
                if (m_View->CanLowerViewpoint() && !m_View->IsExtendedElevation())
 
1125
                    OnLowerViewpoint(e.m_shiftDown);
 
1126
            } else {
 
1127
                OnShiftDisplayDown(e.m_shiftDown);
 
1128
            }
 
1129
            break;
 
1130
        case WXK_ESCAPE:
 
1131
            if (m_View->ShowingMeasuringLine()) {
 
1132
                OnCancelDistLine();
 
1133
            }
 
1134
            break;
 
1135
        default:
 
1136
            e.Skip();
 
1137
    }
 
1138
 
 
1139
    //if (refresh) m_View->ForceRefresh();
 
1140
}
 
1141
 
 
1142
void GUIControl::OnViewFullScreenUpdate(wxUpdateUIEvent& cmd)
 
1143
{
 
1144
    cmd.Check(m_View->IsFullScreen());
 
1145
}
 
1146
 
 
1147
void GUIControl::OnViewFullScreen()
 
1148
{
 
1149
    m_View->FullScreenMode();
 
1150
}
 
1151
 
 
1152
void GUIControl::OnViewBoundingBoxUpdate(wxUpdateUIEvent& cmd)
 
1153
{
 
1154
    cmd.Enable(m_View->HasData());
 
1155
    cmd.Check(m_View->DisplayingBoundingBox());
 
1156
}
 
1157
 
 
1158
void GUIControl::OnViewBoundingBox()
 
1159
{
 
1160
    m_View->ToggleBoundingBox();
 
1161
}