diff options
Diffstat (limited to '')
-rw-r--r-- | src/spectro_source.cc | 329 |
1 files changed, 189 insertions, 140 deletions
diff --git a/src/spectro_source.cc b/src/spectro_source.cc index e0dc802..5a694dc 100644 --- a/src/spectro_source.cc +++ b/src/spectro_source.cc @@ -33,7 +33,6 @@ #include "base/ansi_scrubber.hh" #include "base/math_util.hh" -#include "command_executor.hh" #include "config.h" nonstd::optional<size_t> @@ -83,7 +82,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) return true; } auto begin_time = begin_time_opt.value(); - struct timeval end_time = begin_time; + struct timeval end_time = begin_time.ri_time; end_time.tv_sec += this->ss_granularity; double range_min, range_max, column_size; @@ -94,7 +93,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) + this->ss_cursor_column.value_or(0) * column_size; range_max = range_min + column_size; this->ss_value_source->spectro_mark((textview_curses&) lv, - begin_time.tv_sec, + begin_time.ri_time.tv_sec, end_time.tv_sec, range_min, range_max); @@ -103,7 +102,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) return true; } - case KEY_CTRL_A: { + case KEY_CTRL('a'): { if (this->ss_value_source != nullptr) { this->ss_cursor_column = 0; this->text_selection_changed((textview_curses&) lv); @@ -112,7 +111,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) return true; } - case KEY_CTRL_E: { + case KEY_CTRL('e'): { if (this->ss_value_source != nullptr) { this->ss_cursor_column = INT_MAX; this->text_selection_changed((textview_curses&) lv); @@ -133,6 +132,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) this->text_attrs_for_line((textview_curses&) lv, sel, sa); if (sa.empty()) { + this->ss_details_source.reset(); this->ss_cursor_column = nonstd::nullopt; return true; } @@ -166,6 +166,7 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) } } this->ss_cursor_column = current->sa_range.lr_start; + this->ss_details_source.reset(); lv.reload_data(); @@ -177,152 +178,120 @@ spectrogram_source::list_input_handle_key(listview_curses& lv, int ch) } bool -spectrogram_source::list_value_for_overlay(const listview_curses& lv, - int y, - int bottom, - vis_line_t row, - attr_line_t& value_out) +spectrogram_source::text_handle_mouse( + textview_curses& tc, + const listview_curses::display_line_content_t&, + mouse_event& me) { - vis_line_t height; - unsigned long width; - - lv.get_dimensions(height, width); - width -= 2; + auto sel = tc.get_selection(); + const auto& s_row = this->load_row(tc, sel); - if (y > 0) { - auto sel = lv.get_selection(); - auto selected_y = sel - lv.get_top() + 2; + for (int lpc = 0; lpc <= (int) s_row.sr_width; lpc++) { + int col_value = s_row.sr_values[lpc].rb_counter; - if (y == selected_y && this->ss_cursor_column) { - const auto& s_row = this->load_row(lv, sel); - const auto& bucket - = s_row.sr_values[this->ss_cursor_column.value()]; - auto& sb = this->ss_cached_bounds; - spectrogram_request sr(sb); - - auto sel_time = rounddown(sb.sb_begin_time, this->ss_granularity) - + sel * this->ss_granularity; - sr.sr_width = width; - sr.sr_begin_time = sel_time; - sr.sr_end_time = sel_time + this->ss_granularity; - sr.sr_column_size = (sb.sb_max_value_out - sb.sb_min_value_out) - / (double) (width - 1); - auto range_min = sb.sb_min_value_out - + this->ss_cursor_column.value() * sr.sr_column_size; - auto range_max = range_min + sr.sr_column_size; - - auto desc - = attr_line_t() - .append(lnav::roles::number( - fmt::to_string(bucket.rb_counter))) - .append(fmt::format(FMT_STRING(" value{} in the range "), - bucket.rb_counter == 1 ? "" : "s")) - .append(lnav::roles::number( - fmt::format(FMT_STRING("{:.2Lf}"), range_min))) - .append("-") - .append(lnav::roles::number( - fmt::format(FMT_STRING("{:.2Lf}"), range_max))) - .append(" "); - auto mark_offset = this->ss_cursor_column.value(); - auto mark_is_before = true; - - value_out.al_attrs.emplace_back( - line_range{0, -1}, VC_ROLE.value(role_t::VCR_STATUS_INFO)); - if (desc.length() + 8 > width) { - desc.clear(); - } + if (col_value == 0) { + continue; + } - if (this->ss_cursor_column.value() + desc.length() + 1 > width) { - mark_offset -= desc.length(); - mark_is_before = false; - } - value_out.append(mark_offset, ' '); - if (mark_is_before) { - value_out.append("\u25b2 "); - } - value_out.append(desc); - if (!mark_is_before) { - value_out.append("\u25b2 "); - } + auto lr = line_range{lpc, lpc + 1}; + if (me.is_click_in(mouse_button_t::BUTTON_LEFT, lr)) { + this->ss_cursor_column = lr.lr_start; + this->ss_details_source.reset(); - if (this->ss_details_view != nullptr) { - if (s_row.sr_details_source_provider) { - auto row_details_source = s_row.sr_details_source_provider( - sr, range_min, range_max); - - this->ss_details_view->set_sub_source( - row_details_source.get()); - this->ss_details_source = std::move(row_details_source); - auto* overlay_source = dynamic_cast<list_overlay_source*>( - this->ss_details_source.get()); - if (overlay_source != nullptr) { - this->ss_details_view->set_overlay_source( - overlay_source); - } - } else { - this->ss_details_view->set_sub_source( - this->ss_no_details_source); - this->ss_details_view->set_overlay_source(nullptr); - } - } + tc.reload_data(); return true; } - - return false; } - auto& line = value_out.get_string(); - char buf[128]; + return false; +} - this->cache_bounds(); +void +spectrogram_source::list_value_for_overlay(const listview_curses& lv, + vis_line_t row, + std::vector<attr_line_t>& value_out) +{ + vis_line_t height; + unsigned long width; - if (this->ss_cached_line_count == 0) { - value_out - .append(lnav::roles::error("error: no data available, use the ")) - .append_quoted(lnav::roles::keyword(":spectrogram")) - .append(lnav::roles::error(" command to visualize numeric data")); - return true; - } + lv.get_dimensions(height, width); + width -= 2; - auto& sb = this->ss_cached_bounds; - auto& st = this->ss_cached_thresholds; + auto sel = lv.get_selection(); + + if (row == sel && this->ss_cursor_column) { + const auto& s_row = this->load_row(lv, sel); + const auto& bucket = s_row.sr_values[this->ss_cursor_column.value()]; + auto& sb = this->ss_cached_bounds; + spectrogram_request sr(sb); + attr_line_t retval; + + auto sel_time = rounddown(sb.sb_begin_time, this->ss_granularity) + + sel * this->ss_granularity; + sr.sr_width = width; + sr.sr_begin_time = sel_time; + sr.sr_end_time = sel_time + this->ss_granularity; + sr.sr_column_size = (sb.sb_max_value_out - sb.sb_min_value_out) + / (double) (width - 1); + auto range_min = sb.sb_min_value_out + + this->ss_cursor_column.value() * sr.sr_column_size; + auto range_max = range_min + sr.sr_column_size; + + auto desc + = attr_line_t() + .append( + lnav::roles::number(fmt::to_string(bucket.rb_counter))) + .append(fmt::format(FMT_STRING(" value{} in the range "), + bucket.rb_counter == 1 ? "" : "s")) + .append(lnav::roles::number( + fmt::format(FMT_STRING("{:.2Lf}"), range_min))) + .append("-") + .append(lnav::roles::number( + fmt::format(FMT_STRING("{:.2Lf}"), range_max))) + .append(" "); + auto mark_offset = this->ss_cursor_column.value(); + auto mark_is_before = true; + + retval.al_attrs.emplace_back(line_range{0, -1}, + VC_ROLE.value(role_t::VCR_STATUS_INFO)); + if (desc.length() + 8 > width) { + desc.clear(); + } - snprintf(buf, sizeof(buf), "Min: %'.10lg", sb.sb_min_value_out); - line = buf; + if (this->ss_cursor_column.value() + desc.length() + 1 > width) { + mark_offset -= desc.length(); + mark_is_before = false; + } + retval.append(mark_offset, ' '); + if (mark_is_before) { + retval.append("\u25b2 "); + } + retval.append(desc); + if (!mark_is_before) { + retval.append("\u25b2 "); + } - snprintf(buf, - sizeof(buf), - ANSI_ROLE(" ") " 1-%'d " ANSI_ROLE(" ") " %'d-%'d " ANSI_ROLE( - " ") " %'d+", - role_t::VCR_LOW_THRESHOLD, - st.st_green_threshold - 1, - role_t::VCR_MED_THRESHOLD, - st.st_green_threshold, - st.st_yellow_threshold - 1, - role_t::VCR_HIGH_THRESHOLD, - st.st_yellow_threshold); - auto buflen = strlen(buf); - if (line.length() + buflen + 20 < width) { - line.append(width / 2 - buflen / 3 - line.length(), ' '); - } else { - line.append(" "); - } - line.append(buf); - scrub_ansi_string(line, &value_out.get_attrs()); + if (this->ss_details_view != nullptr) { + if (s_row.sr_details_source_provider) { + auto row_details_source = s_row.sr_details_source_provider( + sr, range_min, range_max); + + this->ss_details_view->set_sub_source(row_details_source.get()); + this->ss_details_source = std::move(row_details_source); + auto* overlay_source = dynamic_cast<list_overlay_source*>( + this->ss_details_source.get()); + if (overlay_source != nullptr) { + this->ss_details_view->set_overlay_source(overlay_source); + } + } else { + this->ss_details_view->set_sub_source( + this->ss_no_details_source); + this->ss_details_view->set_overlay_source(nullptr); + } + } - snprintf(buf, sizeof(buf), "Max: %'.10lg", sb.sb_max_value_out); - buflen = strlen(buf); - if (line.length() + buflen + 4 < width) { - line.append(width - buflen - line.length() - 2, ' '); - } else { - line.append(" "); + value_out.emplace_back(retval); } - line.append(buf); - - value_out.with_attr(string_attr(line_range(0, -1), - VC_STYLE.value(text_attrs{A_UNDERLINE}))); - - return true; } size_t @@ -351,7 +320,7 @@ spectrogram_source::text_line_width(textview_curses& tc) return width; } -nonstd::optional<struct timeval> +nonstd::optional<text_time_translator::row_info> spectrogram_source::time_for_row(vis_line_t row) { if (this->ss_details_source != nullptr) { @@ -366,7 +335,7 @@ spectrogram_source::time_for_row(vis_line_t row) return this->time_for_row_int(row); } -nonstd::optional<struct timeval> +nonstd::optional<text_time_translator::row_info> spectrogram_source::time_for_row_int(vis_line_t row) { struct timeval retval { @@ -378,7 +347,7 @@ spectrogram_source::time_for_row_int(vis_line_t row) = rounddown(this->ss_cached_bounds.sb_begin_time, this->ss_granularity) + row * this->ss_granularity; - return retval; + return row_info{retval, row}; } nonstd::optional<vis_line_t> @@ -419,9 +388,9 @@ spectrogram_source::text_value_for_line(textview_curses& tc, value_out.clear(); return; } - auto row_time = row_time_opt.value(); + auto ri = row_time_opt.value(); - gmtime_r(&row_time.tv_sec, &tm); + gmtime_r(&ri.ri_time.tv_sec, &tm); strftime(tm_buffer, sizeof(tm_buffer), " %a %b %d %H:%M:%S", &tm); value_out = tm_buffer; @@ -464,6 +433,12 @@ spectrogram_source::text_attrs_for_line(textview_curses& tc, } value_out.emplace_back(line_range(lpc, lpc + 1), VC_ROLE.value(role)); } + + auto alt_row_index = row % 4; + if (alt_row_index == 2 || alt_row_index == 3) { + value_out.emplace_back(line_range{0, -1}, + VC_ROLE.value(role_t::VCR_ALT_ROW)); + } } void @@ -582,12 +557,86 @@ spectrogram_source::text_selection_changed(textview_curses& tc) { if (this->ss_value_source == nullptr || this->text_line_count() == 0) { this->ss_cursor_column = nonstd::nullopt; + this->ss_details_source.reset(); return; } + if (tc.get_selection() == -1_vl) { + tc.set_selection(0_vl); + } const auto& s_row = this->load_row(tc, tc.get_selection()); this->ss_cursor_column = s_row.nearest_column(this->ss_cursor_column.value_or(0)); + this->ss_details_source.reset(); +} + +bool +spectrogram_source::list_static_overlay(const listview_curses& lv, + int y, + int bottom, + attr_line_t& value_out) +{ + if (y != 0) { + return false; + } + + auto& line = value_out.get_string(); + vis_line_t height; + unsigned long width; + char buf[128]; + + lv.get_dimensions(height, width); + width -= 2; + + this->cache_bounds(); + + if (this->ss_cached_line_count == 0) { + value_out + .append(lnav::roles::error("error: no data available, use the ")) + .append_quoted(lnav::roles::keyword(":spectrogram")) + .append(lnav::roles::error(" command to visualize numeric data")); + return true; + } + + auto& sb = this->ss_cached_bounds; + auto& st = this->ss_cached_thresholds; + + snprintf(buf, sizeof(buf), "Min: %'.10lg", sb.sb_min_value_out); + line = buf; + + snprintf(buf, + sizeof(buf), + ANSI_ROLE(" ") " 1-%'d " ANSI_ROLE(" ") " %'d-%'d " ANSI_ROLE( + " ") " %'d+", + role_t::VCR_LOW_THRESHOLD, + st.st_green_threshold - 1, + role_t::VCR_MED_THRESHOLD, + st.st_green_threshold, + st.st_yellow_threshold - 1, + role_t::VCR_HIGH_THRESHOLD, + st.st_yellow_threshold); + auto buflen = strlen(buf); + if (line.length() + buflen + 20 < width) { + line.append(width / 2 - buflen / 3 - line.length(), ' '); + } else { + line.append(" "); + } + line.append(buf); + scrub_ansi_string(line, &value_out.get_attrs()); + + snprintf(buf, sizeof(buf), "Max: %'.10lg", sb.sb_max_value_out); + buflen = strlen(buf); + if (line.length() + buflen + 4 < width) { + line.append(width - buflen - line.length() - 2, ' '); + } else { + line.append(" "); + } + line.append(buf); + + value_out.with_attr(string_attr(line_range(0, -1), + VC_STYLE.value(text_attrs{A_UNDERLINE}))); + + return true; } spectro_status_source::spectro_status_source() |