diff --git a/nanovna.h b/nanovna.h index 4a98dc9..49dac8d 100644 --- a/nanovna.h +++ b/nanovna.h @@ -238,6 +238,9 @@ void markmap_all_markers(void); void marker_position(int m, int t, int *x, int *y); int search_nearest_index(int x, int y, int t); +int marker_search(int mode); +int marker_search_left(int from); +int marker_search_right(int from); extern uint16_t redraw_request; diff --git a/plot.c b/plot.c index b4efe1d..3a83fcc 100644 --- a/plot.c +++ b/plot.c @@ -1073,6 +1073,94 @@ marker_position(int m, int t, int *x, int *y) *y = CELL_Y(index); } +static int greater(int x, int y) { return x > y; } +static int lesser(int x, int y) { return x < y; } + +static int (*compare)(int x, int y) = lesser; + + +int +marker_search(int mode) +{ + int i; + int found = 0; + + if (mode == 0) + compare = greater; + else + compare = lesser; + + if (uistat.current_trace == -1) + return -1; + + int value = CELL_Y(trace_index[uistat.current_trace][0]); + for (i = 0; i < 101; i++) { + uint32_t index = trace_index[uistat.current_trace][i]; + if ((*compare)(value, CELL_Y(index))) { + value = CELL_Y(index); + found = i; + } + } + + return found; +} + +int +marker_search_left(int from) +{ + int i; + int found = -1; + + if (uistat.current_trace == -1) + return -1; + + int value = CELL_Y(trace_index[uistat.current_trace][from]); + for (i = from - 1; i >= 0; i--) { + uint32_t index = trace_index[uistat.current_trace][i]; + if ((*compare)(value, CELL_Y(index))) + break; + value = CELL_Y(index); + } + + for (; i >= 0; i--) { + uint32_t index = trace_index[uistat.current_trace][i]; + if ((*compare)(CELL_Y(index), value)) { + break; + } + found = i; + value = CELL_Y(index); + } + return found; +} + +int +marker_search_right(int from) +{ + int i; + int found = -1; + + if (uistat.current_trace == -1) + return -1; + + int value = CELL_Y(trace_index[uistat.current_trace][from]); + for (i = from + 1; i < 101; i++) { + uint32_t index = trace_index[uistat.current_trace][i]; + if ((*compare)(value, CELL_Y(index))) + break; + value = CELL_Y(index); + } + + for (; i < 101; i++) { + uint32_t index = trace_index[uistat.current_trace][i]; + if ((*compare)(CELL_Y(index), value)) { + break; + } + found = i; + value = CELL_Y(index); + } + return found; +} + int search_nearest_index(int x, int y, int t) { diff --git a/ui.c b/ui.c index 6333bdc..aa38228 100644 --- a/ui.c +++ b/ui.c @@ -803,16 +803,16 @@ menu_marker_op_cb(int item) return; // no active marker switch (item) { - case 1: /* MARKER->START */ + case 0: /* MARKER->START */ set_sweep_frequency(ST_START, freq); break; - case 2: /* MARKER->STOP */ + case 1: /* MARKER->STOP */ set_sweep_frequency(ST_STOP, freq); break; - case 3: /* MARKER->CENTER */ + case 2: /* MARKER->CENTER */ set_sweep_frequency(ST_CENTER, freq); break; - case 4: /* MARKERS->SPAN */ + case 3: /* MARKERS->SPAN */ { if (previous_marker == active_marker) return; @@ -838,6 +838,37 @@ menu_marker_op_cb(int item) //redraw_all(); } +static void +menu_marker_search_cb(int item) +{ + int i; + if (active_marker == -1) + return; + + switch (item) { + case 0: /* maximum */ + case 1: /* minimum */ + i = marker_search(item); + if (i != -1) + markers[active_marker].index = i; + draw_menu(); + break; + case 2: /* search Left */ + i = marker_search_left(markers[active_marker].index); + if (i != -1) + markers[active_marker].index = i; + draw_menu(); + break; + case 3: /* search right */ + i = marker_search_right(markers[active_marker].index); + if (i != -1) + markers[active_marker].index = i; + draw_menu(); + break; + } + redraw_marker(active_marker, TRUE); +} + void active_marker_select(int item) { @@ -1011,8 +1042,7 @@ const menuitem_t menu_marker_sel[] = { { MT_NONE, NULL, NULL } // sentinel }; -const menuitem_t menu_marker[] = { - { MT_SUBMENU, "\2SELECT\0MARKER", menu_marker_sel }, +const menuitem_t menu_marker_ops[] = { { MT_CALLBACK, S_RARROW"START", menu_marker_op_cb }, { MT_CALLBACK, S_RARROW"STOP", menu_marker_op_cb }, { MT_CALLBACK, S_RARROW"CENTER", menu_marker_op_cb }, @@ -1021,6 +1051,25 @@ const menuitem_t menu_marker[] = { { MT_NONE, NULL, NULL } // sentinel }; +const menuitem_t menu_marker_search[] = { + //{ MT_CALLBACK, "OFF", menu_marker_search_cb }, + { MT_CALLBACK, "MAXIMUM", menu_marker_search_cb }, + { MT_CALLBACK, "MINIMUM", menu_marker_search_cb }, + { MT_CALLBACK, "\2SEARCH\0" S_LARROW" LEFT", menu_marker_search_cb }, + { MT_CALLBACK, "\2SEARCH\0" S_RARROW" RIGHT", menu_marker_search_cb }, + //{ MT_CALLBACK, "TRACKING", menu_marker_search_cb }, + { MT_CANCEL, S_LARROW" BACK", NULL }, + { MT_NONE, NULL, NULL } // sentinel +}; + +const menuitem_t menu_marker[] = { + { MT_SUBMENU, "\2SELECT\0MARKER", menu_marker_sel }, + { MT_SUBMENU, "SEARCH", menu_marker_search }, + { MT_SUBMENU, "OPERATIONS", menu_marker_ops }, + { MT_CANCEL, S_LARROW" BACK", NULL }, + { MT_NONE, NULL, NULL } // sentinel +}; + const menuitem_t menu_recall[] = { { MT_CALLBACK, "RECALL 0", menu_recall_cb }, { MT_CALLBACK, "RECALL 1", menu_recall_cb },