Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 38fd84541508
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2ebf0935dac9
Choose a head ref
  • 1 commit
  • 6 files changed
  • 1 contributor

Commits on Apr 28, 2021

  1. Initial implementation of horizontal cursors. Shared by all waveforms…

    … in a group. Doesn't handle mixed units too well. Fixes #85.
    azonenberg committed Apr 28, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2ebf093 View commit details
Showing with 272 additions and 60 deletions.
  1. +1 −1 lib
  2. +0 −2 src/glscopeclient/OscilloscopeWindow.cpp
  3. +16 −0 src/glscopeclient/WaveformArea.cpp
  4. +8 −3 src/glscopeclient/WaveformArea.h
  5. +117 −21 src/glscopeclient/WaveformArea_cairo.cpp
  6. +130 −33 src/glscopeclient/WaveformArea_events.cpp
2 changes: 1 addition & 1 deletion lib
Submodule lib updated 1 files
+11 −1 scopehal/FlowGraphNode.cpp
2 changes: 0 additions & 2 deletions src/glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -1552,8 +1552,6 @@ void OscilloscopeWindow::LoadUIConfiguration(const YAML::Node& node, IDTable& ta
group->m_xAxisOffset *= 1000;
group->m_xCursorPos[0] *= 1000;
group->m_xCursorPos[1] *= 1000;
group->m_yCursorPos[0] *= 1000;
group->m_yCursorPos[1] *= 1000;
}

//TODO: statistics
16 changes: 16 additions & 0 deletions src/glscopeclient/WaveformArea.cpp
Original file line number Diff line number Diff line change
@@ -232,6 +232,22 @@ void WaveformArea::CreateWidgets()
sigc::mem_fun(*this, &WaveformArea::OnCursorConfig),
WaveformGroup::CURSOR_X_DUAL,
&m_cursorDualVerticalItem));
m_cursorMenu.append(m_cursorSingleHorizontalItem);
m_cursorSingleHorizontalItem.set_label("Horizontal (single)");
m_cursorSingleHorizontalItem.set_group(m_cursorGroup);
m_cursorSingleHorizontalItem.signal_activate().connect(
sigc::bind<WaveformGroup::CursorConfig, Gtk::RadioMenuItem*>(
sigc::mem_fun(*this, &WaveformArea::OnCursorConfig),
WaveformGroup::CURSOR_Y_SINGLE,
&m_cursorSingleHorizontalItem));
m_cursorMenu.append(m_cursorDualHorizontalItem);
m_cursorDualHorizontalItem.set_label("Horizontal (dual)");
m_cursorDualHorizontalItem.set_group(m_cursorGroup);
m_cursorDualHorizontalItem.signal_activate().connect(
sigc::bind<WaveformGroup::CursorConfig, Gtk::RadioMenuItem*>(
sigc::mem_fun(*this, &WaveformArea::OnCursorConfig),
WaveformGroup::CURSOR_Y_DUAL,
&m_cursorDualHorizontalItem));

m_contextMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem));

11 changes: 8 additions & 3 deletions src/glscopeclient/WaveformArea.h
Original file line number Diff line number Diff line change
@@ -207,7 +207,7 @@ class WaveformArea : public Gtk::GLArea
virtual bool on_scroll_event (GdkEventScroll* ev);
virtual bool on_motion_notify_event(GdkEventMotion* event);

void OnSingleClick(GdkEventButton* event, int64_t timestamp);
void OnSingleClick(GdkEventButton* event, int64_t timestamp, float voltage);
void OnDoubleClick(GdkEventButton* event, int64_t timestamp);

void RescaleEye(Filter* f, EyeWaveform* eye);
@@ -223,6 +223,8 @@ class WaveformArea : public Gtk::GLArea
Gtk::RadioMenuItem m_cursorNoneItem;
Gtk::RadioMenuItem m_cursorSingleVerticalItem;
Gtk::RadioMenuItem m_cursorDualVerticalItem;
Gtk::RadioMenuItem m_cursorSingleHorizontalItem;
Gtk::RadioMenuItem m_cursorDualHorizontalItem;
Gtk::MenuItem m_moveItem;
Gtk::Menu m_moveMenu;
Gtk::MenuItem m_moveNewGroupBelowItem;
@@ -356,7 +358,8 @@ class WaveformArea : public Gtk::GLArea
void RenderCursors(Cairo::RefPtr< Cairo::Context > cr);
void RenderInBandPower(Cairo::RefPtr< Cairo::Context > cr);
void RenderInsertionBar(Cairo::RefPtr< Cairo::Context > cr);
void RenderCursor(Cairo::RefPtr< Cairo::Context > cr, int64_t pos, Gdk::Color color, bool label_to_left);
void RenderVerticalCursor(Cairo::RefPtr< Cairo::Context > cr, int64_t pos, Gdk::Color color, bool label_to_left);
void RenderHorizontalCursor(Cairo::RefPtr< Cairo::Context > cr, float pos, Gdk::Color color, bool label_to_top);
void RenderChannelLabel(Cairo::RefPtr< Cairo::Context > cr);
void RenderEyeMask(Cairo::RefPtr< Cairo::Context > cr);
void RenderDecodeOverlays(Cairo::RefPtr< Cairo::Context > cr);
@@ -437,7 +440,9 @@ class WaveformArea : public Gtk::GLArea
LOC_TRIGGER_SECONDARY, //lower spot for window trigger or similar
LOC_CHAN_NAME,
LOC_XCURSOR_0,
LOC_XCURSOR_1
LOC_XCURSOR_1,
LOC_YCURSOR_0,
LOC_YCURSOR_1
} m_clickLocation;

ClickLocation HitTest(double x, double y);
138 changes: 117 additions & 21 deletions src/glscopeclient/WaveformArea_cairo.cpp
Original file line number Diff line number Diff line change
@@ -699,7 +699,11 @@ void WaveformArea::RenderChannelInfoBox(
cr->restore();
}

void WaveformArea::RenderCursor(Cairo::RefPtr< Cairo::Context > cr, int64_t pos, Gdk::Color color, bool label_to_left)
void WaveformArea::RenderVerticalCursor(
Cairo::RefPtr< Cairo::Context > cr,
int64_t pos,
Gdk::Color color,
bool label_to_left)
{
//Draw the actual cursor
double x = XAxisUnitsToXPosition(pos);
@@ -755,6 +759,62 @@ void WaveformArea::RenderCursor(Cairo::RefPtr< Cairo::Context > cr, int64_t pos,
cr->restore();
}

void WaveformArea::RenderHorizontalCursor(
Cairo::RefPtr< Cairo::Context > cr,
float pos,
Gdk::Color color,
bool label_to_top)
{
//Draw the actual cursor
double y = YAxisUnitsToYPosition(pos);
cr->set_source_rgb(color.get_red_p(), color.get_green_p(), color.get_blue_p());
cr->move_to(0, y);
cr->line_to(m_width, y);
cr->stroke();

//Draw the value label at the right side
string text = m_channel.m_channel->GetYAxisUnits().PrettyPrint(pos);

//Figure out text size
int twidth;
int theight;
Glib::RefPtr<Pango::Layout> tlayout = Pango::Layout::create(get_pango_context());
tlayout->set_font_description(m_cursorLabelFont);
tlayout->set_text(text);
tlayout->get_pixel_size(twidth, theight);

//Draw background
int labelmargin = 2;
int top;
int bottom;
if(label_to_top)
{
bottom = y - labelmargin;
top = y - (theight + 2*labelmargin);
}
else
{
top = y + labelmargin;
bottom = y + (theight + 2*labelmargin);
}
int right = m_width;
int left = m_width - (twidth + 2*labelmargin);
cr->set_source_rgba(0, 0, 0, 0.75);
cr->move_to(left, bottom);
cr->line_to(right, bottom);
cr->line_to(right, top);
cr->line_to(left, top);
cr->fill();

//Draw text
cr->set_source_rgb(color.get_red_p(), color.get_green_p(), color.get_blue_p());
cr->save();
cr->move_to(labelmargin + left, top + labelmargin);
tlayout->update_from_cairo_context(cr);
tlayout->show_in_cairo_context(cr);
cr->restore();
}

/**
@brief Gets the value of our channel at the specified timestamp (absolute, not waveform ticks)
*/
@@ -786,34 +846,70 @@ void WaveformArea::RenderCursors(Cairo::RefPtr< Cairo::Context > cr)

Gdk::Color cursor1 = m_parent->GetPreferences().GetColor("Appearance.Cursors.cursor_1_color");
Gdk::Color cursor2 = m_parent->GetPreferences().GetColor("Appearance.Cursors.cursor_2_color");
Gdk::Color cursor_fill = m_parent->GetPreferences().GetColor("Appearance.Cursors.cursor_fill_color");

if( (m_group->m_cursorConfig == WaveformGroup::CURSOR_X_DUAL) ||
(m_group->m_cursorConfig == WaveformGroup::CURSOR_X_SINGLE) )
switch(m_group->m_cursorConfig)
{
//Draw first vertical cursor
double x = XAxisUnitsToXPosition(m_group->m_xCursorPos[0]);
RenderCursor(cr, m_group->m_xCursorPos[0], cursor1, true);

//Dual cursors
if(m_group->m_cursorConfig == WaveformGroup::CURSOR_X_DUAL)
{
//Draw second vertical cursor
double x2 = XAxisUnitsToXPosition(m_group->m_xCursorPos[1]);
RenderCursor(cr, m_group->m_xCursorPos[1], cursor2, false);
//Draw the second vertical cursor
case WaveformGroup::CURSOR_X_DUAL:

//Draw filled area between them
Gdk::Color cursor_fill = m_parent->GetPreferences().GetColor("Appearance.Cursors.cursor_fill_color");
cr->set_source_rgba(cursor_fill.get_red_p(), cursor_fill.get_green_p(), cursor_fill.get_blue_p(), 0.2);
cr->move_to(x, ytop);
cr->line_to(x2, ytop);
cr->line_to(x2, ybot);
cr->line_to(x, ybot);
cr->fill();
{
double x = XAxisUnitsToXPosition(m_group->m_xCursorPos[0]);
double x2 = XAxisUnitsToXPosition(m_group->m_xCursorPos[1]);
cr->set_source_rgba(cursor_fill.get_red_p(), cursor_fill.get_green_p(), cursor_fill.get_blue_p(), 0.2);
cr->move_to(x, ytop);
cr->line_to(x2, ytop);
cr->line_to(x2, ybot);
cr->line_to(x, ybot);
cr->fill();
}

//If it's a FFT trace, render in-band power
if(m_channel.m_channel->GetXAxisUnits() == Unit::UNIT_HZ)
RenderInBandPower(cr);
}

//Render the second cursor
RenderVerticalCursor(cr, m_group->m_xCursorPos[1], cursor2, false);

//fall through

//Draw first vertical cursor
case WaveformGroup::CURSOR_X_SINGLE:
RenderVerticalCursor(cr, m_group->m_xCursorPos[0], cursor1, true);
break;

//Draw second horizontal cursor
case WaveformGroup::CURSOR_Y_DUAL:

if(IsDigital())
break;

//Render the second cursor
RenderHorizontalCursor(cr, m_group->m_yCursorPos[1], cursor2, false);

//Draw filled area between them
{
double y = YAxisUnitsToYPosition(m_group->m_yCursorPos[0]);
double y2 = YAxisUnitsToYPosition(m_group->m_yCursorPos[1]);
cr->set_source_rgba(cursor_fill.get_red_p(), cursor_fill.get_green_p(), cursor_fill.get_blue_p(), 0.2);
cr->move_to(0, y);
cr->line_to(m_width, y);
cr->line_to(m_width, y2);
cr->line_to(0, y2);
cr->fill();
}

//fall through

//Draw first horizontal cursor
case WaveformGroup::CURSOR_Y_SINGLE:
if(!IsDigital())
RenderHorizontalCursor(cr, m_group->m_yCursorPos[0], cursor1, true);
break;

default:
break;
}
}

Loading