summaryrefslogtreecommitdiffstats
path: root/src/spectro_source.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/spectro_source.cc329
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()