2015-01-04 17:11:20 -05:00
# include "TuningCanvas.h"
# include "wx/wxprec.h"
# ifndef WX_PRECOMP
# include "wx/wx.h"
# endif
# if !wxUSE_GLCANVAS
# error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
# endif
# include "CubicSDR.h"
# include "CubicSDRDefs.h"
# include "AppFrame.h"
# include <algorithm>
wxBEGIN_EVENT_TABLE ( TuningCanvas , wxGLCanvas ) EVT_PAINT ( TuningCanvas : : OnPaint )
EVT_IDLE ( TuningCanvas : : OnIdle )
EVT_MOTION ( TuningCanvas : : OnMouseMoved )
EVT_LEFT_DOWN ( TuningCanvas : : OnMouseDown )
EVT_LEFT_UP ( TuningCanvas : : OnMouseReleased )
2015-05-10 21:43:03 -04:00
EVT_RIGHT_DOWN ( TuningCanvas : : OnMouseRightDown )
EVT_RIGHT_UP ( TuningCanvas : : OnMouseRightReleased )
2015-01-04 17:11:20 -05:00
EVT_LEAVE_WINDOW ( TuningCanvas : : OnMouseLeftWindow )
EVT_ENTER_WINDOW ( TuningCanvas : : OnMouseEnterWindow )
2015-04-08 18:37:40 -04:00
EVT_MOUSEWHEEL ( TuningCanvas : : OnMouseWheelMoved )
2015-04-22 22:54:48 -04:00
EVT_KEY_DOWN ( TuningCanvas : : OnKeyDown )
EVT_KEY_UP ( TuningCanvas : : OnKeyUp )
2015-01-04 17:11:20 -05:00
wxEND_EVENT_TABLE ( )
TuningCanvas : : TuningCanvas ( wxWindow * parent , int * attribList ) :
2015-08-08 13:26:53 -04:00
InteractiveCanvas ( parent , attribList ) , dragAccum ( 0 ) , uxDown ( 0 ) , top ( false ) , bottom ( false ) , freq ( - 1 ) , bw ( - 1 ) , center ( - 1 ) {
2015-01-04 17:11:20 -05:00
glContext = new TuningContext ( this , & wxGetApp ( ) . GetContext ( this ) ) ;
2015-03-26 20:12:54 -04:00
hoverIndex = 0 ;
2015-03-28 01:11:33 -04:00
downIndex = 0 ;
2015-03-26 20:12:54 -04:00
hoverState = TUNING_HOVER_NONE ;
2015-03-28 01:11:33 -04:00
downState = TUNING_HOVER_NONE ;
dragging = false ;
2015-03-26 20:12:54 -04:00
freqDP = - 1.0 ;
freqW = ( 1.0 / 3.0 ) * 2.0 ;
bwDP = - 1.0 + ( 2.25 / 3.0 ) ;
bwW = ( 1.0 / 4.0 ) * 2.0 ;
centerDP = - 1.0 + ( 2.0 / 3.0 ) * 2.0 ;
centerW = ( 1.0 / 3.0 ) * 2.0 ;
2015-04-22 22:54:48 -04:00
currentPPM = lastPPM = 0 ;
2015-01-04 17:11:20 -05:00
}
TuningCanvas : : ~ TuningCanvas ( ) {
}
2015-08-08 13:26:53 -04:00
bool TuningCanvas : : changed ( ) {
DemodulatorInstance * activeDemod = wxGetApp ( ) . getDemodMgr ( ) . getLastActiveDemodulator ( ) ;
long long current_freq = 0 ;
if ( activeDemod ! = NULL ) {
freq = activeDemod - > getFrequency ( ) ;
}
long long current_bw = wxGetApp ( ) . getDemodMgr ( ) . getLastBandwidth ( ) ;
long long current_center = wxGetApp ( ) . getFrequency ( ) ;
if ( current_freq ! = freq | | current_bw ! = bw | | current_center ! = center ) {
return true ;
}
return false ;
}
2015-01-04 17:11:20 -05:00
void TuningCanvas : : OnPaint ( wxPaintEvent & WXUNUSED ( event ) ) {
wxPaintDC dc ( this ) ;
const wxSize ClientSize = GetClientSize ( ) ;
2015-08-08 13:26:53 -04:00
2015-01-04 17:11:20 -05:00
glContext - > SetCurrent ( * this ) ;
2015-02-09 20:49:21 -05:00
initGLExtensions ( ) ;
2015-01-04 17:11:20 -05:00
glViewport ( 0 , 0 , ClientSize . x , ClientSize . y ) ;
glContext - > DrawBegin ( ) ;
DemodulatorInstance * activeDemod = wxGetApp ( ) . getDemodMgr ( ) . getLastActiveDemodulator ( ) ;
2015-08-08 13:26:53 -04:00
freq = 0 ;
2015-01-04 17:11:20 -05:00
if ( activeDemod ! = NULL ) {
2015-03-25 22:47:54 -04:00
freq = activeDemod - > getFrequency ( ) ;
2015-01-04 17:11:20 -05:00
}
2015-08-08 13:26:53 -04:00
bw = wxGetApp ( ) . getDemodMgr ( ) . getLastBandwidth ( ) ;
center = wxGetApp ( ) . getFrequency ( ) ;
2015-03-25 22:47:54 -04:00
2015-01-07 20:23:15 -05:00
if ( mouseTracker . mouseDown ( ) ) {
2015-04-02 20:52:33 -04:00
glContext - > Draw ( ThemeMgr : : mgr . currentTheme - > tuningBarDark . r , ThemeMgr : : mgr . currentTheme - > tuningBarDark . g , ThemeMgr : : mgr . currentTheme - > tuningBarDark . b ,
0.75 , mouseTracker . getOriginMouseX ( ) , mouseTracker . getMouseX ( ) ) ;
2015-01-07 20:23:15 -05:00
}
2015-07-31 18:21:30 -04:00
RGB3f clr = top ? ThemeMgr : : mgr . currentTheme - > tuningBarUp : ThemeMgr : : mgr . currentTheme - > tuningBarDown ;
2015-03-26 20:12:54 -04:00
2015-07-31 18:21:30 -04:00
RGB3f clrDark = ThemeMgr : : mgr . currentTheme - > tuningBarDark ;
RGB3f clrMid = ThemeMgr : : mgr . currentTheme - > tuningBarLight ;
2015-03-26 20:12:54 -04:00
2015-03-26 22:45:52 -04:00
glContext - > DrawTunerBarIndexed ( 1 , 3 , 11 , freqDP , freqW , clrMid , 0.25 , true , true ) ; // freq
glContext - > DrawTunerBarIndexed ( 4 , 6 , 11 , freqDP , freqW , clrDark , 0.25 , true , true ) ;
glContext - > DrawTunerBarIndexed ( 7 , 9 , 11 , freqDP , freqW , clrMid , 0.25 , true , true ) ;
glContext - > DrawTunerBarIndexed ( 10 , 11 , 11 , freqDP , freqW , clrDark , 0.25 , true , true ) ;
2015-03-26 20:12:54 -04:00
2015-03-26 22:45:52 -04:00
glContext - > DrawTunerBarIndexed ( 1 , 3 , 7 , bwDP , bwW , clrMid , 0.25 , true , true ) ; // bw
glContext - > DrawTunerBarIndexed ( 4 , 6 , 7 , bwDP , bwW , clrDark , 0.25 , true , true ) ;
glContext - > DrawTunerBarIndexed ( 7 , 7 , 7 , bwDP , bwW , clrMid , 0.25 , true , true ) ;
2015-03-26 20:12:54 -04:00
2015-03-26 22:45:52 -04:00
glContext - > DrawTunerBarIndexed ( 1 , 3 , 11 , centerDP , centerW , clrMid , 0.25 , true , true ) ; // freq
glContext - > DrawTunerBarIndexed ( 4 , 6 , 11 , centerDP , centerW , clrDark , 0.25 , true , true ) ;
glContext - > DrawTunerBarIndexed ( 7 , 9 , 11 , centerDP , centerW , clrMid , 0.25 , true , true ) ;
glContext - > DrawTunerBarIndexed ( 10 , 11 , 11 , centerDP , centerW , clrDark , 0.25 , true , true ) ;
2015-03-26 20:12:54 -04:00
2015-03-28 00:59:04 -04:00
if ( hoverIndex > 0 & & ! mouseTracker . mouseDown ( ) ) {
2015-03-26 20:12:54 -04:00
switch ( hoverState ) {
case TUNING_HOVER_FREQ :
glContext - > DrawTunerBarIndexed ( hoverIndex , hoverIndex , 11 , freqDP , freqW , clr , 0.25 , top , bottom ) ; // freq
break ;
case TUNING_HOVER_BW :
glContext - > DrawTunerBarIndexed ( hoverIndex , hoverIndex , 7 , bwDP , bwW , clr , 0.25 , top , bottom ) ; // bw
break ;
case TUNING_HOVER_CENTER :
glContext - > DrawTunerBarIndexed ( hoverIndex , hoverIndex , 11 , centerDP , centerW , clr , 0.25 , top , bottom ) ; // center
break ;
case TUNING_HOVER_NONE :
break ;
2015-04-22 22:54:48 -04:00
case TUNING_HOVER_PPM :
glContext - > DrawTunerBarIndexed ( hoverIndex , hoverIndex , 11 , freqDP , freqW , clr , 0.25 , top , bottom ) ; // freq
break ;
}
2015-03-25 22:47:54 -04:00
}
2015-04-22 22:54:48 -04:00
if ( altDown ) {
glContext - > DrawTuner ( currentPPM , 11 , freqDP , freqW ) ;
} else {
glContext - > DrawTuner ( freq , 11 , freqDP , freqW ) ;
2015-05-10 21:43:03 -04:00
int snap = wxGetApp ( ) . getFrequencySnap ( ) ;
if ( snap ! = 1 ) {
2015-07-31 18:21:30 -04:00
glContext - > DrawTunerDigitBox ( ( int ) log10 ( snap ) , 11 , freqDP , freqW , RGB3f ( 1.0 , 0.0 , 0.0 ) ) ;
2015-05-10 21:43:03 -04:00
}
2015-04-22 22:54:48 -04:00
}
2015-03-26 20:12:54 -04:00
glContext - > DrawTuner ( bw , 7 , bwDP , bwW ) ;
glContext - > DrawTuner ( center , 11 , centerDP , centerW ) ;
2015-03-25 22:47:54 -04:00
2015-01-04 17:11:20 -05:00
glContext - > DrawEnd ( ) ;
SwapBuffers ( ) ;
}
2015-03-28 00:59:04 -04:00
void TuningCanvas : : StepTuner ( ActiveState state , int exponent , bool up ) {
double exp = pow ( 10 , exponent ) ;
long long amount = up ? exp : - exp ;
DemodulatorInstance * activeDemod = wxGetApp ( ) . getDemodMgr ( ) . getLastActiveDemodulator ( ) ;
if ( state = = TUNING_HOVER_FREQ & & activeDemod ) {
long long freq = activeDemod - > getFrequency ( ) ;
long long diff = abs ( wxGetApp ( ) . getFrequency ( ) - freq ) ;
if ( shiftDown ) {
bool carried = ( long long ) ( ( freq ) / ( exp * 10 ) ) ! = ( long long ) ( ( freq + amount ) / ( exp * 10 ) ) | | ( bottom & & freq < exp ) ;
freq + = carried ? ( 9 * - amount ) : amount ;
} else {
freq + = amount ;
}
if ( wxGetApp ( ) . getSampleRate ( ) / 2 < diff ) {
wxGetApp ( ) . setFrequency ( freq ) ;
}
2015-04-23 19:38:44 -04:00
activeDemod - > setTracking ( true ) ;
activeDemod - > setFollow ( true ) ;
2015-03-28 00:59:04 -04:00
activeDemod - > setFrequency ( freq ) ;
activeDemod - > updateLabel ( freq ) ;
}
if ( state = = TUNING_HOVER_BW ) {
long bw = wxGetApp ( ) . getDemodMgr ( ) . getLastBandwidth ( ) ;
if ( shiftDown ) {
bool carried = ( long ) ( ( bw ) / ( exp * 10 ) ) ! = ( long ) ( ( bw + amount ) / ( exp * 10 ) ) | | ( bottom & & bw < exp ) ;
bw + = carried ? ( 9 * - amount ) : amount ;
} else {
bw + = amount ;
}
if ( bw > wxGetApp ( ) . getSampleRate ( ) ) {
bw = wxGetApp ( ) . getSampleRate ( ) ;
}
wxGetApp ( ) . getDemodMgr ( ) . setLastBandwidth ( bw ) ;
if ( activeDemod ) {
activeDemod - > setBandwidth ( wxGetApp ( ) . getDemodMgr ( ) . getLastBandwidth ( ) ) ;
}
}
if ( state = = TUNING_HOVER_CENTER ) {
long long ctr = wxGetApp ( ) . getFrequency ( ) ;
if ( shiftDown ) {
bool carried = ( long long ) ( ( ctr ) / ( exp * 10 ) ) ! = ( long long ) ( ( ctr + amount ) / ( exp * 10 ) ) | | ( bottom & & ctr < exp ) ;
ctr + = carried ? ( 9 * - amount ) : amount ;
} else {
ctr + = amount ;
}
wxGetApp ( ) . setFrequency ( ctr ) ;
}
2015-04-22 22:54:48 -04:00
if ( state = = TUNING_HOVER_PPM ) {
if ( shiftDown ) {
bool carried = ( long long ) ( ( currentPPM ) / ( exp * 10 ) ) ! = ( long long ) ( ( currentPPM + amount ) / ( exp * 10 ) ) | | ( bottom & & currentPPM < exp ) ;
currentPPM + = carried ? ( 9 * - amount ) : amount ;
} else {
currentPPM + = amount ;
}
if ( currentPPM > 2000 ) {
currentPPM = 2000 ;
}
if ( currentPPM < - 2000 ) {
currentPPM = - 2000 ;
}
wxGetApp ( ) . setPPM ( currentPPM ) ;
}
2015-03-28 00:59:04 -04:00
}
2015-01-04 17:11:20 -05:00
void TuningCanvas : : OnIdle ( wxIdleEvent & event ) {
2015-03-28 00:59:04 -04:00
if ( mouseTracker . mouseDown ( ) ) {
if ( downState ! = TUNING_HOVER_NONE ) {
dragAccum + = 5.0 * mouseTracker . getOriginDeltaMouseX ( ) ;
while ( dragAccum > 1.0 ) {
StepTuner ( downState , downIndex - 1 , true ) ;
dragAccum - = 1.0 ;
2015-03-28 01:11:33 -04:00
dragging = true ;
2015-03-28 00:59:04 -04:00
}
while ( dragAccum < - 1.0 ) {
StepTuner ( downState , downIndex - 1 , false ) ;
dragAccum + = 1.0 ;
2015-03-28 01:11:33 -04:00
dragging = true ;
2015-03-28 00:59:04 -04:00
}
} else {
dragAccum = 0 ;
2015-03-28 01:11:33 -04:00
dragging = false ;
2015-03-28 00:59:04 -04:00
}
}
2015-08-12 20:05:57 -04:00
if ( mouseTracker . mouseInView ( ) | | changed ( ) ) {
Refresh ( ) ;
}
2015-08-12 18:07:06 -04:00
event . RequestMore ( ) ;
2015-01-07 20:23:15 -05:00
}
void TuningCanvas : : OnMouseMoved ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseMoved ( event ) ;
2015-03-26 20:12:54 -04:00
int index = 0 ;
2015-03-26 22:45:52 -04:00
top = mouseTracker . getMouseY ( ) > = 0.5 ;
bottom = mouseTracker . getMouseY ( ) < = 0.5 ;
2015-03-26 20:12:54 -04:00
index = glContext - > GetTunerDigitIndex ( mouseTracker . getMouseX ( ) , 11 , freqDP , freqW ) ; // freq
if ( index > 0 ) {
hoverIndex = index ;
2015-04-22 22:54:48 -04:00
hoverState = altDown ? TUNING_HOVER_PPM : TUNING_HOVER_FREQ ;
2015-03-26 20:12:54 -04:00
}
2015-03-29 20:24:00 -04:00
if ( ! index ) {
index = glContext - > GetTunerDigitIndex ( mouseTracker . getMouseX ( ) , 7 , bwDP , bwW ) ; // bw
if ( index > 0 ) {
hoverIndex = index ;
hoverState = TUNING_HOVER_BW ;
}
2015-03-26 20:12:54 -04:00
}
2015-03-29 20:24:00 -04:00
if ( ! index ) {
index = glContext - > GetTunerDigitIndex ( mouseTracker . getMouseX ( ) , 11 , centerDP , centerW ) ; // center
if ( index > 0 ) {
hoverIndex = index ;
hoverState = TUNING_HOVER_CENTER ;
}
2015-03-26 20:12:54 -04:00
}
2015-03-29 20:24:00 -04:00
if ( ! index ) {
hoverIndex = 0 ;
hoverState = TUNING_HOVER_NONE ;
} else {
switch ( hoverState ) {
case TUNING_HOVER_FREQ :
2015-05-10 22:21:13 -04:00
setStatusText ( " Click, wheel or drag a digit to change frequency; SPACE for direct input. Right click to set/clear snap. Hold ALT to change PPM. Hold SHIFT to disable carry. " ) ;
2015-03-29 20:24:00 -04:00
break ;
case TUNING_HOVER_BW :
2015-08-14 21:32:58 -04:00
setStatusText ( " Click, wheel or drag a digit to change bandwidth; SPACE for direct input. Hold SHIFT to disable carry. " ) ;
2015-03-29 20:24:00 -04:00
break ;
case TUNING_HOVER_CENTER :
2015-05-10 02:30:50 -04:00
setStatusText ( " Click, wheel or drag a digit to change center frequency; SPACE for direct input. Hold SHIFT to disable carry. " ) ;
2015-03-29 20:24:00 -04:00
break ;
2015-04-22 22:54:48 -04:00
case TUNING_HOVER_PPM :
2015-04-23 19:38:44 -04:00
setStatusText ( " Click, wheel or drag a digit to change device PPM offset. Hold SHIFT to disable carry. " ) ;
2015-04-22 22:54:48 -04:00
break ;
2015-05-10 02:30:50 -04:00
case TUNING_HOVER_NONE :
setStatusText ( " " ) ;
break ;
2015-04-22 22:54:48 -04:00
}
2015-03-29 20:24:00 -04:00
}
2015-05-10 02:30:50 -04:00
if ( hoverState = = TUNING_HOVER_BW | | hoverState = = TUNING_HOVER_FREQ ) {
wxGetApp ( ) . getDemodMgr ( ) . setActiveDemodulator ( wxGetApp ( ) . getDemodMgr ( ) . getLastActiveDemodulator ( ) ) ;
} else {
wxGetApp ( ) . getDemodMgr ( ) . setActiveDemodulator ( NULL ) ;
}
2015-01-04 17:11:20 -05:00
}
void TuningCanvas : : OnMouseDown ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseDown ( event ) ;
2015-01-04 19:32:51 -05:00
2015-01-07 20:23:15 -05:00
uxDown = 2.0 * ( mouseTracker . getMouseX ( ) - 0.5 ) ;
2015-01-04 19:32:51 -05:00
dragAccum = 0 ;
2015-03-28 00:59:04 -04:00
mouseTracker . setVertDragLock ( true ) ;
downIndex = hoverIndex ;
downState = hoverState ;
2015-01-04 17:11:20 -05:00
}
void TuningCanvas : : OnMouseWheelMoved ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseWheelMoved ( event ) ;
2015-04-08 18:37:40 -04:00
int hExponent = hoverIndex - 1 ;
if ( hoverState ! = TUNING_HOVER_NONE & & ! mouseTracker . mouseDown ( ) & & hoverIndex ) {
if ( event . m_wheelAxis = = wxMOUSE_WHEEL_VERTICAL ) {
StepTuner ( hoverState , hExponent , ( event . m_wheelRotation > 0 ) ? true : false ) ;
} else {
StepTuner ( hoverState , hExponent , ( event . m_wheelRotation < 0 ) ? true : false ) ;
}
}
2015-01-04 17:11:20 -05:00
}
void TuningCanvas : : OnMouseReleased ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseReleased ( event ) ;
2015-03-26 22:45:52 -04:00
int hExponent = hoverIndex - 1 ;
2015-03-27 21:15:24 -04:00
2015-03-29 20:24:00 -04:00
if ( hoverState ! = TUNING_HOVER_NONE & & ! dragging & & ( downState = = hoverState ) & & ( downIndex = = hoverIndex ) ) {
2015-03-28 00:59:04 -04:00
StepTuner ( hoverState , hExponent , top ) ;
2015-03-26 22:45:52 -04:00
}
2015-03-28 00:59:04 -04:00
mouseTracker . setVertDragLock ( false ) ;
2015-03-26 22:45:52 -04:00
2015-03-28 01:11:33 -04:00
dragging = false ;
2015-03-26 20:12:54 -04:00
SetCursor ( wxCURSOR_ARROW ) ;
2015-01-04 17:11:20 -05:00
}
2015-05-10 21:43:03 -04:00
void TuningCanvas : : OnMouseRightDown ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseRightDown ( event ) ;
}
void TuningCanvas : : OnMouseRightReleased ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseRightReleased ( event ) ;
if ( hoverState = = TUNING_HOVER_FREQ ) {
if ( hoverIndex = = 1 ) {
wxGetApp ( ) . setFrequencySnap ( 1 ) ;
} else if ( hoverIndex > 1 & & hoverIndex < 8 ) {
int exp = pow ( 10 , hoverIndex - 1 ) ;
if ( wxGetApp ( ) . getFrequencySnap ( ) = = exp ) {
wxGetApp ( ) . setFrequencySnap ( 1 ) ;
} else {
wxGetApp ( ) . setFrequencySnap ( exp ) ;
}
}
}
}
2015-01-04 17:11:20 -05:00
void TuningCanvas : : OnMouseLeftWindow ( wxMouseEvent & event ) {
InteractiveCanvas : : OnMouseLeftWindow ( event ) ;
2015-01-14 22:14:57 -05:00
SetCursor ( wxCURSOR_CROSS ) ;
2015-03-26 20:12:54 -04:00
hoverIndex = 0 ;
hoverState = TUNING_HOVER_NONE ;
2015-05-10 20:00:48 -04:00
wxGetApp ( ) . getDemodMgr ( ) . setActiveDemodulator ( NULL ) ;
2015-04-22 22:54:48 -04:00
if ( currentPPM ! = lastPPM ) {
wxGetApp ( ) . saveConfig ( ) ;
}
2015-08-08 13:26:53 -04:00
Refresh ( ) ;
2015-01-04 17:11:20 -05:00
}
void TuningCanvas : : OnMouseEnterWindow ( wxMouseEvent & event ) {
InteractiveCanvas : : mouseTracker . OnMouseEnterWindow ( event ) ;
2015-03-26 20:12:54 -04:00
SetCursor ( wxCURSOR_ARROW ) ;
hoverIndex = 0 ;
hoverState = TUNING_HOVER_NONE ;
2015-04-22 22:54:48 -04:00
lastPPM = currentPPM = wxGetApp ( ) . getPPM ( ) ;
2015-01-04 17:11:20 -05:00
}
void TuningCanvas : : setHelpTip ( std : : string tip ) {
helpTip = tip ;
}
2015-04-22 22:54:48 -04:00
void TuningCanvas : : OnKeyDown ( wxKeyEvent & event ) {
InteractiveCanvas : : OnKeyDown ( event ) ;
2015-05-10 02:30:50 -04:00
2015-08-14 20:19:37 -04:00
if ( event . GetKeyCode ( ) = = WXK_SPACE ) {
if ( hoverState = = TUNING_HOVER_CENTER | | hoverState = = TUNING_HOVER_FREQ ) {
wxGetApp ( ) . showFrequencyInput ( FrequencyDialog : : FDIALOG_TARGET_DEFAULT ) ;
} else if ( hoverState = = TUNING_HOVER_BW ) {
wxGetApp ( ) . showFrequencyInput ( FrequencyDialog : : FDIALOG_TARGET_BANDWIDTH ) ;
}
2015-05-10 02:30:50 -04:00
}
2015-04-22 22:54:48 -04:00
}
void TuningCanvas : : OnKeyUp ( wxKeyEvent & event ) {
InteractiveCanvas : : OnKeyUp ( event ) ;
}