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: c3ad881536f1
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: 06200542e716
Choose a head ref
  • 1 commit
  • 5 files changed
  • 1 contributor

Commits on Feb 15, 2020

  1. Protocol decoders now have their own infoboxes instead of just printe…

    …d names, and double clicking the infobox allows editing display name or decode configuration
    azonenberg committed Feb 15, 2020
    Copy the full SHA
    0620054 View commit details
19 changes: 17 additions & 2 deletions glscopeclient/ProtocolDecoderDialog.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -49,6 +49,14 @@ ProtocolDecoderDialog::ProtocolDecoderDialog(
add_button("OK", Gtk::RESPONSE_OK);
add_button("Cancel", Gtk::RESPONSE_CANCEL);

get_vbox()->pack_start(m_channelDisplayNameBox, Gtk::PACK_SHRINK);
m_channelDisplayNameBox.pack_start(m_channelDisplayNameLabel, Gtk::PACK_SHRINK);
m_channelDisplayNameLabel.set_text("Display name");
m_channelDisplayNameBox.pack_start(m_channelDisplayNameEntry, Gtk::PACK_EXPAND_WIDGET);
m_channelDisplayNameLabel.set_size_request(150, 1);
m_channelDisplayNameLabel.set_halign(Gtk::ALIGN_START);
m_channelDisplayNameEntry.set_text(decoder->m_displayname);

for(size_t i=0; i<decoder->GetInputCount(); i++)
{
//Add the row
@@ -74,7 +82,7 @@ ProtocolDecoderDialog::ProtocolDecoderDialog(
{
row->m_chans.append(c->m_displayname);
row->m_chanptrs[c->m_displayname] = c;
if(c == chan)
if( (c == chan) || (c == decoder->GetInput(i)) )
row->m_chans.set_active_text(c->m_displayname);
}
}
@@ -134,6 +142,13 @@ void ProtocolDecoderDialog::ConfigureDecoder()
m_decoder->GetParameter(m_prows[i]->m_label.get_label()).ParseString(
m_prows[i]->m_entry.get_text());
}

//Set the name of the decoder based on the input channels etc
//TODO: do this any time we change an input or configure stuff
m_decoder->SetDefaultName();
auto dname = m_channelDisplayNameEntry.get_text();
if(dname != "")
m_decoder->m_displayname = dname;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6 changes: 5 additions & 1 deletion glscopeclient/ProtocolDecoderDialog.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -90,6 +90,10 @@ class ProtocolDecoderDialog : public Gtk::Dialog
protected:
ProtocolDecoder* m_decoder;

Gtk::HBox m_channelDisplayNameBox;
Gtk::Label m_channelDisplayNameLabel;
Gtk::Entry m_channelDisplayNameEntry;

std::vector<ChannelSelectorRow*> m_rows;
std::vector<ParameterRow*> m_prows;
};
10 changes: 10 additions & 0 deletions glscopeclient/WaveformArea.h
Original file line number Diff line number Diff line change
@@ -284,6 +284,15 @@ class WaveformArea : public Gtk::GLArea
VertexBuffer m_cairoVBO;
Program m_cairoProgram;

//Helpers for rendering and such
void RenderChannelInfoBox(
OscilloscopeChannel* chan,
Cairo::RefPtr< Cairo::Context > cr,
int bottom,
std::string text,
Rect& box,
int labelmargin = 6);

void ResetTextureFiltering();

//Math helpers
@@ -322,6 +331,7 @@ class WaveformArea : public Gtk::GLArea

//Positions of various UI elements used by hit testing
Rect m_infoBoxRect;
std::map<ProtocolDecoder*, Rect> m_overlayBoxRects;

enum ClickLocation
{
42 changes: 34 additions & 8 deletions glscopeclient/WaveformArea_events.cpp
Original file line number Diff line number Diff line change
@@ -330,12 +330,28 @@ void WaveformArea::OnDoubleClick(GdkEventButton* /*event*/, int64_t /*timestamp*
//Double click on channel name to pop up the config dialog
case LOC_CHAN_NAME:
{
ChannelPropertiesDialog dialog(m_parent, m_selectedChannel);
if(dialog.run() == Gtk::RESPONSE_OK)
//See if it's a physical channel
if(m_selectedChannel->IsPhysicalChannel())
{
dialog.ConfigureChannel();
queue_draw();
ChannelPropertiesDialog dialog(m_parent, m_selectedChannel);
if(dialog.run() == Gtk::RESPONSE_OK)
{
dialog.ConfigureChannel();
queue_draw();
}
}

//No, it's a decode
else
{
ProtocolDecoderDialog dialog(m_parent, dynamic_cast<ProtocolDecoder*>(m_selectedChannel), NULL);
if(dialog.run() == Gtk::RESPONSE_OK)
{
dialog.ConfigureDecoder();
queue_draw();
}
}

}
break;

@@ -511,9 +527,6 @@ void WaveformArea::OnProtocolDecode(string name)
//If the dialog is canceled, don't do anything.
g_numDecodes ++;

//Set the name of the decoder based on the input channels etc
decode->SetDefaultName();

//If it's an eye pattern or waterfall, set the initial size
auto eye = dynamic_cast<EyeDecoder2*>(decode);
if(eye != NULL)
@@ -614,9 +627,22 @@ void WaveformArea::OnWaveformDataReady()
*/
WaveformArea::ClickLocation WaveformArea::HitTest(double x, double y)
{
//On the channel name button?
//On the main channel name button?
if(m_infoBoxRect.HitTest(x, y))
{
m_selectedChannel = m_channel;
return LOC_CHAN_NAME;
}

//On an overlay info box?
for(auto it : m_overlayBoxRects)
{
if(it.second.HitTest(x, y))
{
m_selectedChannel = it.first;
return LOC_CHAN_NAME;
}
}

if(x > m_plotRight)
{
128 changes: 63 additions & 65 deletions glscopeclient/WaveformArea_rendering.cpp
Original file line number Diff line number Diff line change
@@ -759,9 +759,10 @@ void WaveformArea::DoRenderCairoOverlays(Cairo::RefPtr< Cairo::Context > cr)

void WaveformArea::RenderDecodeOverlays(Cairo::RefPtr< Cairo::Context > cr)
{
int midline = 15;
//TODO: adjust height/spacing depending on font sizes etc
int height = 20;
int spacing = 30;
int midline = spacing / 2;

//Find which overlay slots are in use
int max_overlays = 10;
@@ -811,21 +812,11 @@ void WaveformArea::RenderDecodeOverlays(Cairo::RefPtr< Cairo::Context > cr)
cr->line_to(0, ybot);
cr->fill();

//Render the channel label
cr->set_source_rgba(1,1,1,1);
int twidth;
int theight;
Glib::RefPtr<Pango::Layout> tlayout = Pango::Layout::create (cr);
Pango::FontDescription font("monospace normal 10");
font.set_weight(Pango::WEIGHT_NORMAL);
tlayout->set_font_description(font);
tlayout->set_text(o->m_displayname);
tlayout->get_pixel_size(twidth, theight);
cr->move_to(5, ybot - theight);
tlayout->update_from_cairo_context(cr);
tlayout->show_in_cairo_context(cr);
Rect chanbox;
RenderChannelInfoBox(o, cr, ybot, o->m_displayname, chanbox, 2);
m_overlayBoxRects[o] = chanbox;

int textright = twidth + 10;
int textright = chanbox.get_right() + 4;

if(data == NULL)
continue;
@@ -910,99 +901,106 @@ void WaveformArea::RenderDecodeOverlays(Cairo::RefPtr< Cairo::Context > cr)
}
}

void WaveformArea::RenderChannelLabel(Cairo::RefPtr< Cairo::Context > cr)
void WaveformArea::RenderChannelInfoBox(
OscilloscopeChannel* chan,
Cairo::RefPtr< Cairo::Context > cr,
int bottom,
string text,
Rect& box,
int labelmargin)
{
auto ybot = m_height;

//Figure out text size
int twidth;
int theight;
Glib::RefPtr<Pango::Layout> tlayout = Pango::Layout::create (cr);
Pango::FontDescription font("sans normal 10");
font.set_weight(Pango::WEIGHT_NORMAL);
tlayout->set_font_description(font);

//Add sample rate info to physical channels
//TODO: do this to some decodes too?
string label = m_channel->m_displayname;
auto data = m_channel->GetData();
if(m_channel->IsPhysicalChannel() && (data != NULL) )
{
label += " : ";

//Format sample depth
char tmp[256];
size_t len = data->GetDepth();
if(len > 1e6)
snprintf(tmp, sizeof(tmp), "%.0f MS", len * 1e-6f);
else if(len > 1e3)
snprintf(tmp, sizeof(tmp), "%.0f kS", len * 1e-3f);
else
snprintf(tmp, sizeof(tmp), "%zu S", len);
label += tmp;
label += "\n";

//Format timebase
double gsps = 1000.0f / data->m_timescale;
if(gsps > 1)
snprintf(tmp, sizeof(tmp), "%.0f GS/s", gsps);
else if(gsps > 0.001)
snprintf(tmp, sizeof(tmp), "%.0f MS/s", gsps * 1000);
else
snprintf(tmp, sizeof(tmp), "%.1f kS/s", gsps * 1000 * 1000);
label += tmp;
}

tlayout->set_text(label);
tlayout->set_text(text);
tlayout->get_pixel_size(twidth, theight);

//Channel-colored rounded outline
cr->save();

int labelmargin = 6;
int labelheight = theight + labelmargin*2;

m_infoBoxRect.set_x(2);
m_infoBoxRect.set_y(ybot - labelheight - 1);
m_infoBoxRect.set_width(twidth + labelmargin*2);
m_infoBoxRect.set_height(labelheight);
box.set_x(2);
box.set_y(bottom - labelheight - 1);
box.set_width(twidth + labelmargin*2);
box.set_height(labelheight);

Rect innerBox = m_infoBoxRect;
Rect innerBox = box;
innerBox.shrink(labelmargin, labelmargin);

//Path for the outline
cr->begin_new_sub_path();
cr->arc(innerBox.get_left(), innerBox.get_bottom(), labelmargin, M_PI_2, M_PI); //bottom left
cr->line_to(m_infoBoxRect.get_left(), innerBox.get_y());
cr->line_to(box.get_left(), innerBox.get_y());
cr->arc(innerBox.get_left(), innerBox.get_top(), labelmargin, M_PI, 1.5*M_PI); //top left
cr->line_to(innerBox.get_right(), m_infoBoxRect.get_top());
cr->line_to(innerBox.get_right(), box.get_top());
cr->arc(innerBox.get_right(), innerBox.get_top(), labelmargin, 1.5*M_PI, 2*M_PI); //top right
cr->line_to(m_infoBoxRect.get_right(), innerBox.get_bottom());
cr->line_to(box.get_right(), innerBox.get_bottom());
cr->arc(innerBox.get_right(), innerBox.get_bottom(), labelmargin, 2*M_PI, M_PI_2); //bottom right
cr->line_to(innerBox.get_left(), m_infoBoxRect.get_bottom());
cr->line_to(innerBox.get_left(), box.get_bottom());

//Fill it
cr->set_source_rgba(0, 0, 0, 0.75);
cr->fill_preserve();

//Draw the outline
Gdk::Color color(m_channel->m_displaycolor);
Gdk::Color color(chan->m_displaycolor);
cr->set_source_rgba(color.get_red_p(), color.get_green_p(), color.get_blue_p(), 1);

cr->set_line_width(1);

cr->stroke();

cr->restore();

//White text
cr->save();
cr->set_source_rgba(1, 1, 1, 1);
cr->move_to(labelmargin, ybot - theight - labelmargin);
cr->move_to(labelmargin, bottom - theight - labelmargin);
tlayout->update_from_cairo_context(cr);
tlayout->show_in_cairo_context(cr);
cr->restore();
}

void WaveformArea::RenderChannelLabel(Cairo::RefPtr< Cairo::Context > cr)
{
//Add sample rate info to physical channels
//TODO: do this to some decodes too?
string label = m_channel->m_displayname;
auto data = m_channel->GetData();
if(m_channel->IsPhysicalChannel() && (data != NULL) )
{
label += " : ";

//Format sample depth
char tmp[256];
size_t len = data->GetDepth();
if(len > 1e6)
snprintf(tmp, sizeof(tmp), "%.0f MS", len * 1e-6f);
else if(len > 1e3)
snprintf(tmp, sizeof(tmp), "%.0f kS", len * 1e-3f);
else
snprintf(tmp, sizeof(tmp), "%zu S", len);
label += tmp;
label += "\n";

//Format timebase
double gsps = 1000.0f / data->m_timescale;
if(gsps > 1)
snprintf(tmp, sizeof(tmp), "%.0f GS/s", gsps);
else if(gsps > 0.001)
snprintf(tmp, sizeof(tmp), "%.0f MS/s", gsps * 1000);
else
snprintf(tmp, sizeof(tmp), "%.1f kS/s", gsps * 1000 * 1000);
label += tmp;
}

//Do the actual drawing
RenderChannelInfoBox(m_channel, cr, m_height, label, m_infoBoxRect);
}

void WaveformArea::RenderCursors(Cairo::RefPtr< Cairo::Context > cr)
{
int ytop = m_height;