Skip to content

Commit 10027ae

Browse files
authored
Merge pull request #951 from fredzo/instrument-manager-rework
Instrument manager rework
2 parents 087d04f + 4ea0bbb commit 10027ae

12 files changed

Lines changed: 334 additions & 88 deletions

src/ngscopeclient/AddInstrumentDialog.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ AddInstrumentDialog::AddInstrumentDialog(
4747
const string& nickname,
4848
Session* session,
4949
MainWindow* parent,
50-
const string& driverType)
50+
const string& driverType,
51+
const std::string& driver,
52+
const std::string& transport,
53+
const std::string& path)
5154
: Dialog(
5255
title,
5356
string("AddInstrument") + to_string_hex(reinterpret_cast<uintptr_t>(this)),
@@ -57,10 +60,39 @@ AddInstrumentDialog::AddInstrumentDialog(
5760
, m_nickname(nickname)
5861
, m_selectedDriver(0)
5962
, m_selectedTransport(0)
63+
, m_path(path)
6064
{
6165
SCPITransport::EnumTransports(m_transports);
6266

6367
m_drivers = session->GetDriverNamesForType(driverType);
68+
if(!driver.empty())
69+
{
70+
int i = 0;
71+
for(auto driverName: m_drivers)
72+
{
73+
if(driverName == driver)
74+
{
75+
m_selectedDriver = i;
76+
break;
77+
}
78+
i++;
79+
}
80+
}
81+
82+
83+
if(!transport.empty())
84+
{
85+
int i = 0;
86+
for(auto transportName: m_transports)
87+
{
88+
if(transportName == transport)
89+
{
90+
m_selectedTransport = i;
91+
break;
92+
}
93+
i++;
94+
}
95+
}
6496
}
6597

6698
AddInstrumentDialog::~AddInstrumentDialog()
@@ -218,6 +250,5 @@ SCPITransport* AddInstrumentDialog::MakeTransport()
218250

219251
bool AddInstrumentDialog::DoConnect(SCPITransport* transport)
220252
{
221-
m_session->CreateAndAddInstrument(m_drivers[m_selectedDriver], transport, m_nickname);
222-
return true;
253+
return m_session->CreateAndAddInstrument(m_drivers[m_selectedDriver], transport, m_nickname);
223254
}

src/ngscopeclient/AddInstrumentDialog.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ class AddInstrumentDialog : public Dialog
4646
const std::string& nickname,
4747
Session* session,
4848
MainWindow* parent,
49-
const std::string& driverType);
49+
const std::string& driverType,
50+
const std::string& driver = "",
51+
const std::string& transport = "",
52+
const std::string& path = "");
5053
virtual ~AddInstrumentDialog();
5154

5255
virtual bool DoRender();

src/ngscopeclient/Dialog.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ bool Dialog::TextInputWithImplicitApply(const string& label, string& currentValu
244244
return false;
245245
}
246246

247+
bool Dialog::TextInputWithExplicitApply(const string& label, string& currentValue, string& committedValue)
248+
{
249+
return renderEditablePropertyWithExplicitApply(-1,label,currentValue,committedValue,Unit()/*not used for string*/);
250+
}
251+
247252
bool Dialog::IntInputWithImplicitApply(const string& label, int& currentValue, int& committedValue)
248253
{
249254
bool dirty = currentValue != committedValue;
@@ -495,7 +500,7 @@ template<typename T>
495500
*/
496501
bool Dialog::renderEditableProperty(float width, const std::string& label, std::string& currentValue, T& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay, bool explicitApply)
497502
{
498-
static_assert(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, int64_t>,"renderEditableProperty only supports int64_t, float or double");
503+
static_assert(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, int64_t> || std::is_same_v<T, std::string>,"renderEditableProperty only supports string, int64_t, float or double");
499504
bool use7Segment = false;
500505
bool changeFont = false;
501506
int64_t displayType = NumericValueDisplay::NUMERIC_DISPLAY_DEFAULT_FONT;
@@ -535,6 +540,8 @@ bool Dialog::renderEditableProperty(float width, const std::string& label, std::
535540
}
536541
if constexpr (std::is_same_v<T, int64_t>)
537542
dirty = unit.PrettyPrintInt64(committedValue) != currentValue;
543+
else if constexpr (std::is_same_v<T, std::string>)
544+
dirty = committedValue != currentValue;
538545
else
539546
dirty = unit.PrettyPrint(committedValue) != currentValue;
540547
string editLabel = label+"##Edit";
@@ -681,6 +688,10 @@ bool Dialog::renderEditableProperty(float width, const std::string& label, std::
681688

682689
currentValue = unit.PrettyPrintInt64(committedValue);
683690
}
691+
else if constexpr (std::is_same_v<T, std::string>)
692+
{
693+
committedValue = currentValue;
694+
}
684695
else
685696
{
686697
committedValue = static_cast<T>(unit.ParseString(currentValue));
@@ -696,6 +707,8 @@ bool Dialog::renderEditableProperty(float width, const std::string& label, std::
696707
{ // Restore value
697708
if constexpr (std::is_same_v<T, int64_t>)
698709
currentValue = unit.PrettyPrintInt64(committedValue);
710+
else if constexpr (std::is_same_v<T, std::string>)
711+
currentValue = committedValue;
699712
else
700713
currentValue = unit.PrettyPrint(committedValue);
701714
if(m_editedItemId == editId)
@@ -714,6 +727,7 @@ bool Dialog::renderEditableProperty(float width, const std::string& label, std::
714727
template bool Dialog::renderEditableProperty<float>(float width, const std::string& label, std::string& currentValue, float& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay, bool explicitApply);
715728
template bool Dialog::renderEditableProperty<double>(float width, const std::string& label, std::string& currentValue, double& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay, bool explicitApply);
716729
template bool Dialog::renderEditableProperty<int64_t>(float width, const std::string& label, std::string& currentValue, int64_t& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay, bool explicitApply);
730+
template bool Dialog::renderEditableProperty<std::string>(float width, const std::string& label, std::string& currentValue, std::string& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay, bool explicitApply);
717731

718732
template<typename T>
719733
/**
@@ -738,7 +752,24 @@ bool Dialog::renderEditablePropertyWithExplicitApply(float width, const std::str
738752
template bool Dialog::renderEditablePropertyWithExplicitApply<float>(float width, const std::string& label, std::string& currentValue, float& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay);
739753
template bool Dialog::renderEditablePropertyWithExplicitApply<double>(float width, const std::string& label, std::string& currentValue, double& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay);
740754
template bool Dialog::renderEditablePropertyWithExplicitApply<int64_t>(float width, const std::string& label, std::string& currentValue, int64_t& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay);
755+
template bool Dialog::renderEditablePropertyWithExplicitApply<std::string>(float width, const std::string& label, std::string& currentValue, std::string& committedValue, Unit unit, const char* tooltip, std::optional<ImVec4> optcolor, bool allow7SegmentDisplay);
741756

757+
/**
758+
@brief Render a badge with text inside
759+
@param width the width of the badge
760+
@param color the badge color
761+
@param label the text of the badge
762+
*/
763+
void Dialog::renderBadge(float width, ImVec4 color, const string& label)
764+
{
765+
float fontSize = ImGui::GetFontSize();
766+
if(width <= 0) width = 6*fontSize;
767+
ImGui::PushStyleColor(ImGuiCol_ChildBg, color);
768+
ImGui::BeginChild("##badge", ImVec2(width, ImGui::GetFontSize()),false,ImGuiWindowFlags_None);
769+
ImGui::TextUnformatted(label.c_str());
770+
ImGui::EndChild();
771+
ImGui::PopStyleColor();
772+
}
742773

743774
/**
744775
@brief Segment on/off state for each of the 10 digits + "L" (needed for OL / Overload)

src/ngscopeclient/Dialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Dialog
8181
std::string& committedValue);
8282

8383
protected:
84+
bool TextInputWithExplicitApply(const std::string& label,std::string& currentValue,std::string& committedValue);
8485
bool IntInputWithImplicitApply(const std::string& label, int& currentValue, int& committedValue);
8586
bool UnitInputWithExplicitApply(
8687
const std::string& label,
@@ -93,6 +94,7 @@ class Dialog
9394
bool renderEditableProperty(float width, const std::string& label, std::string& currentValue, T& committedValue, Unit unit, const char* tooltip = nullptr, std::optional<ImVec4> optcolor = std::nullopt, bool allow7SegmentDisplay = false, bool explicitApply = false);
9495
template<typename T>
9596
bool renderEditablePropertyWithExplicitApply(float width, const std::string& label, std::string& currentValue, T& committedValue, Unit unit, const char* tooltip = nullptr, std::optional<ImVec4> optcolor = std::nullopt, bool allow7SegmentDisplay = false);
97+
void renderBadge(float width, ImVec4 color, const std::string& label);
9698

9799
public:
98100
static void Tooltip(const std::string& str, bool allowDisabled = false);

src/ngscopeclient/MainWindow.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,10 +1595,14 @@ void MainWindow::SaveRecentInstrumentList()
15951595
continue;
15961596

15971597
//Make a node for the instrument
1598-
YAML::Node inode;
1599-
inode["path"] = it.first;
1600-
inode["timestamp"] = static_cast<int64_t>(it.second);
1601-
node[nick] = inode;
1598+
int64_t timestamp = static_cast<int64_t>(it.second);
1599+
if(!node[nick] || (node[nick]["timestamp"].as<int64_t>() < timestamp))
1600+
{ // Only add node if not already present or if other timestamp is older
1601+
YAML::Node inode;
1602+
inode["path"] = it.first;
1603+
inode["timestamp"] = timestamp;
1604+
node[nick] = inode;
1605+
}
16021606
}
16031607

16041608
//Write the generated YAML to disk
@@ -1659,6 +1663,64 @@ void MainWindow::AddToRecentInstrumentList(shared_ptr<SCPIInstrument> inst)
16591663
SaveRecentInstrumentList();
16601664
}
16611665

1666+
void MainWindow::RenameRecentInstrument(std::shared_ptr<SCPIInstrument> inst, const std::string& oldName)
1667+
{
1668+
if(inst == nullptr)
1669+
return;
1670+
1671+
LogTrace("Renaming instrument \"%s\" with name \"%s\" in recent instrument list (had %zu)\n",
1672+
oldName.c_str(), inst->m_nickname.c_str(), m_recentInstruments.size());
1673+
1674+
auto oldConnectionString =
1675+
oldName + ":" +
1676+
inst->GetDriverName() + ":" +
1677+
inst->GetTransportName() + ":" +
1678+
inst->GetTransportConnectionString();
1679+
auto it = m_recentInstruments.find(oldConnectionString);
1680+
if (it != m_recentInstruments.end())
1681+
{
1682+
auto now = time(NULL);
1683+
auto newConnectionString =
1684+
inst->m_nickname + ":" +
1685+
inst->GetDriverName() + ":" +
1686+
inst->GetTransportName() + ":" +
1687+
inst->GetTransportConnectionString();
1688+
LogTrace("Replaced connection string %s by %s\n", oldConnectionString.c_str(),newConnectionString.c_str());
1689+
m_recentInstruments.erase(it);
1690+
m_recentInstruments.emplace(newConnectionString, now);
1691+
SaveRecentInstrumentList();
1692+
}
1693+
}
1694+
1695+
void MainWindow::RepathRecentInstrument(std::shared_ptr<SCPIInstrument> inst, const std::string& oldPath)
1696+
{
1697+
if(inst == nullptr)
1698+
return;
1699+
1700+
LogTrace("Changing path for instrument \"%s\" with path \"%s\" in recent instrument list (had %zu)\n",
1701+
oldPath.c_str(), inst->GetTransportConnectionString().c_str(), m_recentInstruments.size());
1702+
1703+
auto oldConnectionString =
1704+
inst->m_nickname + ":" +
1705+
inst->GetDriverName() + ":" +
1706+
inst->GetTransportName() + ":" +
1707+
oldPath;
1708+
auto it = m_recentInstruments.find(oldConnectionString);
1709+
if (it != m_recentInstruments.end())
1710+
{
1711+
auto now = time(NULL);
1712+
auto newConnectionString =
1713+
inst->m_nickname + ":" +
1714+
inst->GetDriverName() + ":" +
1715+
inst->GetTransportName() + ":" +
1716+
inst->GetTransportConnectionString();
1717+
LogTrace("Replaced connection string %s by %s\n", oldConnectionString.c_str(),newConnectionString.c_str());
1718+
m_recentInstruments.erase(it);
1719+
m_recentInstruments.emplace(newConnectionString, now);
1720+
SaveRecentInstrumentList();
1721+
}
1722+
}
1723+
16621724
/**
16631725
@brief Helper function for creating a transport and printing an error if the connection is unsuccessful
16641726
*/
@@ -1805,6 +1867,9 @@ ImGui::MarkdownConfig MainWindow::GetMarkdownConfig()
18051867
*/
18061868
void MainWindow::RenderLoadWarningPopup()
18071869
{
1870+
if(!m_errorPopupTitle.empty())
1871+
return; // Already showing Error popup, skip Warning for now
1872+
18081873
static ImGuiTableFlags flags =
18091874
ImGuiTableFlags_Resizable |
18101875
ImGuiTableFlags_BordersOuter |

src/ngscopeclient/MainWindow.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ class MainWindow : public VulkanWindow
514514

515515
public:
516516
void AddToRecentInstrumentList(std::shared_ptr<SCPIInstrument> inst);
517+
void RenameRecentInstrument(std::shared_ptr<SCPIInstrument> inst, const std::string& oldName);
518+
void RepathRecentInstrument(std::shared_ptr<SCPIInstrument> inst, const std::string& oldPath);
517519

518520
protected:
519521

src/ngscopeclient/MainWindow_Menus.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,31 @@ void MainWindow::DoAddSubMenu(
364364
path = path + ":" + fields[j];
365365
}
366366

367+
bool success = true;
367368
auto transport = MakeTransport(transname, path);
368369
if(transport != nullptr)
369-
m_session.CreateAndAddInstrument(drivername, transport, nick);
370+
{
371+
if(!m_session.CreateAndAddInstrument(drivername, transport, nick))
372+
{
373+
success = false;
374+
}
375+
}
376+
else
377+
{
378+
success = false;
379+
}
380+
if(!success)
381+
{ // Spawn an AddInstrument dialog here, prefilled with intrument informations, to allow changing connection path
382+
m_dialogs.emplace(make_shared<AddInstrumentDialog>(
383+
string("Update ") + typePretty,
384+
nick,
385+
&m_session,
386+
this,
387+
typeInternal,
388+
drivername,
389+
transname,
390+
path));
391+
}
370392
}
371393
}
372394
}

0 commit comments

Comments
 (0)