diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 0611e3ae..e25e6417 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -6,6 +6,7 @@ #include "soundconf.h" #include "combo.h" #include "colorsfonts.h" +#include "waterfall.h" extern void initViewer(); Fl_Double_Window *dlgConfig; @@ -305,6 +306,13 @@ static void cb_inpWaterfallClickText(Fl_Input* o, void*) { progdefaults.changed = true; } +Fl_Choice *mnuWaterfallWheelAction=(Fl_Choice *)0; + +static void cb_mnuWaterfallWheelAction(Fl_Choice* o, void*) { + progdefaults.WaterfallWheelAction = o->value(); +progdefaults.changed = true; +} + Fl_Group *tabVideo=(Fl_Group *)0; Fl_Check_Button *btnsendid=(Fl_Check_Button *)0; @@ -1720,6 +1728,11 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 } // Fl_Input* inpWaterfallClickText o->end(); } // Fl_Group* o + { mnuWaterfallWheelAction = new Fl_Choice(15, 176, 150, 22, "Wheel action"); + mnuWaterfallWheelAction->down_box(FL_BORDER_BOX); + mnuWaterfallWheelAction->callback((Fl_Callback*)cb_mnuWaterfallWheelAction); + mnuWaterfallWheelAction->align(FL_ALIGN_RIGHT); + } // Fl_Choice* mnuWaterfallWheelAction o->end(); } // Fl_Group* o o->end(); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index c660b227..239296c5 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -21,6 +21,8 @@ decl {\#include "combo.h"} {} decl {\#include "colorsfonts.h"} {} +decl {\#include "waterfall.h"} {} + decl {extern void initViewer();} {} decl {Fl_Double_Window *dlgConfig;} {public @@ -380,6 +382,12 @@ progdefaults.changed = true;} xywh {15 126 150 40} align 8 } } + Fl_Choice mnuWaterfallWheelAction { + label {Wheel action} + callback {progdefaults.WaterfallWheelAction = o->value(); +progdefaults.changed = true;} open + xywh {15 176 150 22} down_box BORDER_BOX align 8 + } {} } } } diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 7c542b00..7f2ca757 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -2506,57 +2506,6 @@ void setReverse(int rev) { active_modem->set_reverse(rev); } -void change_modem_param(int state) -{ - int d; - if ( !((d = Fl::event_dy()) || (d = Fl::event_dx())) ) - return; - - if (state & (FL_META | FL_ALT)) { - if (d > 0) - active_modem->searchUp(); - else if (d < 0) - active_modem->searchDown(); - return; - } - if (!(state & (FL_CTRL | FL_SHIFT))) - return; // suggestions? - - Fl_Valuator *val; - if (state & FL_CTRL) { - trx_mode m = active_modem->get_mode(); - if (m >= MODE_PSK_FIRST && m <= MODE_PSK_LAST) - val = mailserver ? cntServerOffset : cntSearchRange; - else if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST) - val = sldrHellBW; - else if (m == MODE_CW) - val = sldrCWbandwidth; - else - return; - } - else if (state & FL_SHIFT) { - val = sldrSquelch; - if (!twoscopes) - d = -d; - } - - val->value(val->clamp(val->increment(val->value(), -d))); - bool changed_save = progdefaults.changed; - val->do_callback(); - progdefaults.changed = changed_save; - if (val == cntServerOffset || val == cntSearchRange) - active_modem->set_sigsearch(SIGSEARCH); - else if (val == sldrSquelch) // sldrSquelch gives focus to TextWidget - wf->take_focus(); - - char msg[60]; - if (val != sldrSquelch) - snprintf(msg, sizeof(msg), "%s = %2.0f Hz", val->label(), val->value()); - else - snprintf(msg, sizeof(msg), "Squelch = %2.0f %%", val->value()); - put_status(msg, 2); -} - void start_tx() { if (progdefaults.rsid == true) return; diff --git a/src/include/confdialog.h b/src/include/confdialog.h index f948a1e0..46691415 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -48,6 +48,8 @@ extern Fl_Button *btnBwTracksColor; extern Fl_Check_Button *btnWaterfallHistoryDefault; extern Fl_Check_Button *btnWaterfallQSY; extern Fl_Input *inpWaterfallClickText; +#include +extern Fl_Choice *mnuWaterfallWheelAction; extern Fl_Group *tabVideo; extern Fl_Check_Button *btnsendid; extern Fl_Check_Button *btnsendvideotext; @@ -71,7 +73,6 @@ extern Fl_Input_Choice *inpTTYdev; extern Fl_Round_Button *btnPTT[5]; extern Fl_Check_Button *chkUSEHAMLIB; extern Fl_ComboBox *cboHamlibRig; -#include extern Fl_Choice *mnuBaudRate; extern Fl_Input_Choice *inpRIGdev; extern Fl_Check_Button *chkUSERIGCAT; diff --git a/src/include/configuration.h b/src/include/configuration.h index 316f3dbf..1b9f08f0 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -29,6 +29,7 @@ struct configuration { bool WaterfallHistoryDefault; bool WaterfallQSY; string WaterfallClickText; + int WaterfallWheelAction; // for PSK & PSK mail interface bool PSKmailSweetSpot; int SearchRange; diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index ab0a3bae..46b01011 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -156,8 +156,6 @@ extern bool QuerySqlOnOff(); extern void init_modem(trx_mode mode); extern void init_modem_sync(trx_mode mode); -extern void change_modem_param(int state); - extern void start_tx(); extern void abort_tx(); diff --git a/src/include/waterfall.h b/src/include/waterfall.h index 07ab72a9..b20d1902 100644 --- a/src/include/waterfall.h +++ b/src/include/waterfall.h @@ -158,7 +158,6 @@ public: void draw(); // void resize (int, int, int, int); int handle(int event); - void handle_mouse_wheel(int event); void update_sigmap(); void update_waterfall(); void checkoffset(); @@ -365,8 +364,12 @@ public: double Pwr(int i) { return wfdisp->Pwr(i); } int handle(int event); -/* -*/ + + enum { WF_NOP, WF_AFC_BW, WF_SIGNAL_SEARCH, WF_SQUELCH, + WF_CARRIER, WF_MODEM, WF_SCROLL }; + static const char wf_wheel_action[]; + void handle_mouse_wheel(int what, int d); + Fl_Button *btnRev; Fl_Counter *wfcarrier; Fl_Counter *wfRefLevel; diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index 455659cb..548e752b 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -4,6 +4,7 @@ #include "confdialog.h" #include "xmlreader.h" #include "soundconf.h" +#include "waterfall.h" #if USE_HAMLIB #include "hamlib.h" @@ -47,6 +48,7 @@ configuration progdefaults = { false, // bool WaterfallHistoryDefault; false, // bool WaterfallQSY; "", // string WaterfallClickText; + waterfall::WF_CARRIER, // int WaterfallWheelAction; // for PSK mail interface false, // bool PSKmailSweetSpot; @@ -292,7 +294,7 @@ enum TAG { \ IGNORE, MYCALL, MYNAME, MYQTH, MYLOC, SQUELCH, WFREFLEVEL, WFAMPSPAN, LOWFREQCUTOFF, - WATERFALLHISTORYDEFAULT, WATERFALLQSY, WATERFALLCLICKTEXT, + WATERFALLHISTORYDEFAULT, WATERFALLQSY, WATERFALLCLICKTEXT, WATERFALLWHEELACTION, STARTATSWEETSPOT, PSKMAILSWEETSPOT, PSKSEARCHRANGE, PSKSERVEROFFSET, ACQSN, @@ -430,6 +432,7 @@ void configuration::writeDefaultsXML() writeXMLbool(f, "WATERFALLHISTORYDEFAULT", WaterfallHistoryDefault); writeXMLbool(f, "WATERFALLQSY", WaterfallQSY); writeXMLstr(f, "WATERFALLCLICKTEXT", WaterfallClickText); + writeXMLint(f, "WATERFALLWHEELACTION", WaterfallWheelAction); writeXMLbool(f, "STARTATSWEETSPOT", StartAtSweetSpot); writeXMLbool(f, "PSKMAILSWEETSPOT", PSKmailSweetSpot); writeXMLint(f, "PSKSEARCHRANGE", SearchRange); @@ -679,6 +682,9 @@ bool configuration::readDefaultsXML() case WATERFALLCLICKTEXT : WaterfallClickText = getstring(xml); break; + case WATERFALLWHEELACTION : + WaterfallWheelAction = atoi(getstring(xml).c_str()); + break; case STARTATSWEETSPOT : StartAtSweetSpot = atoi(getstring(xml).c_str()); break; @@ -1224,6 +1230,7 @@ bool configuration::readDefaultsXML() else if (!strcmp("WATERFALLHISTORYDEFAULT", nodeName)) tag = WATERFALLHISTORYDEFAULT; else if (!strcmp("WATERFALLQSY", nodeName)) tag = WATERFALLQSY; else if (!strcmp("WATERFALLCLICKTEXT", nodeName)) tag = WATERFALLCLICKTEXT; + else if (!strcmp("WATERFALLWHEELACTION", nodeName)) tag = WATERFALLWHEELACTION; else if (!strcmp("STARTATSWEETSPOT", nodeName)) tag = STARTATSWEETSPOT; else if (!strcmp("PSKMAILSWEETSPOT", nodeName)) tag = PSKMAILSWEETSPOT; else if (!strcmp("PSKSEARCHRANGE", nodeName)) tag = PSKSEARCHRANGE; @@ -1565,6 +1572,10 @@ int configuration::setDefaults() { btnWaterfallQSY->value(WaterfallQSY); inpWaterfallClickText->input_type(FL_MULTILINE_INPUT); inpWaterfallClickText->value(WaterfallClickText.c_str()); + + mnuWaterfallWheelAction->add(waterfall::wf_wheel_action); + mnuWaterfallWheelAction->value(WaterfallWheelAction); + btnStartAtSweetSpot->value(StartAtSweetSpot); btnPSKmailSweetSpot->value(PSKmailSweetSpot); cntSearchRange->value(SearchRange); diff --git a/src/waterfall/digiscope.cxx b/src/waterfall/digiscope.cxx index f316f477..3f3a99ce 100644 --- a/src/waterfall/digiscope.cxx +++ b/src/waterfall/digiscope.cxx @@ -472,7 +472,8 @@ int Digiscope::handle(int event) } return 1; case FL_MOUSEWHEEL: - change_modem_param(FL_CTRL); + if ((event = Fl::event_dy()) || (event = Fl::event_dx())) + wf->handle_mouse_wheel(waterfall::WF_AFC_BW, event); break; default: break; diff --git a/src/waterfall/waterfall.cxx b/src/waterfall/waterfall.cxx index 9c00d30a..94c5d98a 100644 --- a/src/waterfall/waterfall.cxx +++ b/src/waterfall/waterfall.cxx @@ -48,6 +48,7 @@ #include "Viewer.h" #include "macros.h" #include "arq_io.h" +#include "confdialog.h" extern modem *active_modem; @@ -1551,10 +1552,25 @@ int WFdisp::handle(int event) break; case FL_MOUSEWHEEL: - change_modem_param(Fl::event_state()); + { + int d; + if ( !((d = Fl::event_dy()) || (d = Fl::event_dx())) ) + break; + int state = Fl::event_state(); + if (state & FL_CTRL) + wf->handle_mouse_wheel(waterfall::WF_AFC_BW, d); + else if (state & (FL_META | FL_ALT)) + wf->handle_mouse_wheel(waterfall::WF_SIGNAL_SEARCH, d); + else if (state & FL_SHIFT) + wf->handle_mouse_wheel(waterfall::WF_SQUELCH, d); + else { + if (progdefaults.WaterfallQSY && Fl::event_inside(x(), y(), w(), WFTEXT+WFSCALE+WFMARKER)) + qsy(wf->rfcarrier() - 500*d); + else + wf->handle_mouse_wheel(progdefaults.WaterfallWheelAction, d); + } return handle(FL_MOVE); - break; - + } case FL_SHORTCUT: if (Fl::event_inside(this)) take_focus(); @@ -1606,3 +1622,71 @@ int WFdisp::handle(int event) return 1; } + +void waterfall::handle_mouse_wheel(int what, int d) +{ + if (d == 0) + return; + + Fl_Valuator *val = 0; + const char* msg_fmt = 0, *msg_label = 0; + + switch (what) { + case WF_NOP: + return; + case WF_AFC_BW: + { + trx_mode m = active_modem->get_mode(); + if (m >= MODE_PSK_FIRST && m <= MODE_PSK_LAST) + val = mailserver ? cntServerOffset : cntSearchRange; + else if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST) + val = sldrHellBW; + else if (m == MODE_CW) + val = sldrCWbandwidth; + msg_fmt = "%s = %2.0f Hz"; + msg_label = val->label(); + break; + } + case WF_SIGNAL_SEARCH: + if (d > 0) + active_modem->searchDown(); + else + active_modem->searchUp(); + return; + case WF_SQUELCH: + val = sldrSquelch; + if (!twoscopes) + d = -d; + msg_fmt = "%s = %2.0f %%"; + msg_label = "Squelch"; + break; + case WF_CARRIER: + val = wfcarrier; + break; + case WF_MODEM: + init_modem(d > 0 ? MODE_NEXT : MODE_PREV); + return; + case WF_SCROLL: + (d > 0 ? right : left)->do_callback(); + return; + } + + val->value(val->clamp(val->increment(val->value(), -d))); + bool changed_save = progdefaults.changed; + val->do_callback(); + progdefaults.changed = changed_save; + if (val == cntServerOffset || val == cntSearchRange) + active_modem->set_sigsearch(SIGSEARCH); + else if (val == sldrSquelch) // sldrSquelch gives focus to TransmitText + take_focus(); + + if (msg_fmt) { + char msg[60]; + snprintf(msg, sizeof(msg), msg_fmt, msg_label, val->value()); + put_status(msg, 2.0); + } +} + +const char waterfall::wf_wheel_action[] = "None|AFC range or BW|" + "Signal search|Squelch level|" + "Modem carrier|Modem|Scroll";