stablize the Peer Status display for SysView; refactor rendering of peers for SysView Peer Status; make dvmmon's peer display more similar to SysView;

pull/72/head
Bryan Biedenkapp 1 year ago
parent 4f5369a582
commit 304163ef8b

@ -121,6 +121,8 @@ private:
bool m_control;
bool m_tx;
FString m_tbText{}; // title bar text
lookups::VoiceChData m_chData;
uint8_t m_channelId;
uint32_t m_channelNo;
@ -155,7 +157,8 @@ private:
FDialog::setShadow(false);
FDialog::setModal(false);
FDialog::setText("UNKNOWN");
m_failed = true;
m_tbText = "UNKNOWN";
initControls();
@ -169,7 +172,14 @@ private:
{
FDialog::draw();
setColor();
const auto& wc = getColorTheme();
setForegroundColor(wc->dialog_fg);
setBackgroundColor(wc->dialog_bg);
if (m_failed) {
m_tbText = "FAILED";
setColor(FColor::LightGray, FColor::LightRed);
}
else if (m_control) {
@ -182,7 +192,74 @@ private:
setColor(FColor::LightGray, FColor::Black);
}
finalcut::drawBorder(this, FRect(FPoint{1, 2}, FPoint{NODE_STATUS_WIDTH, NODE_STATUS_HEIGHT}));
finalcut::drawBorder(this, FRect(FPoint{1, 1}, FPoint{NODE_STATUS_WIDTH, NODE_STATUS_HEIGHT + 1}));
if (FVTerm::getFOutput()->isMonochron())
setReverse(true);
drawTitleBar();
setCursorPos({2, int(getHeight()) - 1});
if (FVTerm::getFOutput()->isMonochron())
setReverse(false);
}
/**
* @brief
*/
void drawTitleBar()
{
print() << FPoint{2, 1};
// Fill with spaces (left of the title)
if (FVTerm::getFOutput()->getMaxColor() < 16)
setBold();
const auto& wc = getColorTheme();
if (!m_tx) {
if (m_failed) {
setColor(FColor::Black, FColor::LightRed);
}
else if (m_control) {
setColor(FColor::LightGray, FColor::Purple1);
}
else {
setColor(FColor::Black, FColor::White);
}
} else {
setColor(FColor::Black, FColor::LightGreen);
}
const auto width = getWidth();
auto textWidth = getColumnWidth(m_tbText);
std::size_t leadingSpace{0};
if (width > textWidth)
leadingSpace = ((width - textWidth) / 2) - 1;
// Print leading whitespace
print(FString(leadingSpace, L' '));
// Print title bar text
if (!m_tbText.isEmpty()) {
if (textWidth <= width)
print(m_tbText);
else {
// Print ellipsis
const auto len = getLengthFromColumnWidth(m_tbText, width - 2);
print(m_tbText.left(len));
print("..");
textWidth = len + 2;
}
}
// Print trailing whitespace
std::size_t trailingSpace = (width - leadingSpace - textWidth) - 2;
print(FString(trailingSpace, L' '));
if (FVTerm::getFOutput()->getMaxColor() < 16)
unsetBold();
}
/**
@ -190,16 +267,17 @@ private:
*/
void initControls()
{
m_modeStr.setGeometry(FPoint(22, 1), FSize(4, 1));
m_modeStr.setGeometry(FPoint(23, 1), FSize(4, 1));
m_modeStr.setAlignment(Align::Right);
m_modeStr.setEmphasis();
m_peerIdStr.setGeometry(FPoint(17, 2), FSize(9, 1));
m_peerIdStr.setGeometry(FPoint(18, 2), FSize(9, 1));
m_peerIdStr.setAlignment(Align::Right);
m_peerIdStr.setEmphasis();
// channel number
{
m_channelNoLabel.setGeometry(FPoint(2, 1), FSize(10, 1));
m_channelNoLabel.setGeometry(FPoint(1, 1), FSize(10, 1));
m_chanNo.setGeometry(FPoint(11, 1), FSize(8, 1));
m_chanNo.setText("");
@ -207,18 +285,18 @@ private:
// channel frequency
{
m_txFreqLabel.setGeometry(FPoint(2, 2), FSize(4, 1));
m_txFreqLabel.setGeometry(FPoint(1, 2), FSize(4, 1));
m_txFreq.setGeometry(FPoint(6, 2), FSize(9, 1));
m_txFreq.setText("");
m_rxFreqLabel.setGeometry(FPoint(2, 3), FSize(4, 1));
m_rxFreqLabel.setGeometry(FPoint(1, 3), FSize(4, 1));
m_rxFreq.setGeometry(FPoint(6, 3), FSize(9, 1));
m_rxFreq.setText("");
}
// last TG
{
m_lastDstLabel.setGeometry(FPoint(2, 4), FSize(11, 1));
m_lastDstLabel.setGeometry(FPoint(1, 4), FSize(11, 1));
m_lastDst.setGeometry(FPoint(13, 4), FSize(8, 1));
m_lastDst.setText("None");
@ -226,7 +304,7 @@ private:
// last source
{
m_lastSrcLabel.setGeometry(FPoint(2, 5), FSize(11, 1));
m_lastSrcLabel.setGeometry(FPoint(1, 5), FSize(11, 1));
m_lastSrc.setGeometry(FPoint(13, 5), FSize(8, 1));
m_lastSrc.setText("None");
@ -305,7 +383,7 @@ private:
++m_failCnt;
if (m_failCnt > NODE_UPDATE_FAIL_CNT) {
m_failed = true;
setText("FAILED");
m_tbText = std::string("FAILED");
}
}
else {
@ -330,7 +408,11 @@ private:
if (rsp["peerId"].is<uint32_t>()) {
m_peerId = rsp["peerId"].get<uint32_t>();
m_peerIdStr.setText(__INT_STR(m_peerId));
// pad peer IDs properly
std::ostringstream peerOss;
peerOss << std::setw(9) << std::setfill('0') << m_peerId;
m_peerIdStr.setText(peerOss.str());
}
// get remote node state
@ -346,17 +428,17 @@ private:
// are we a dedicated control channel?
if (dmrCC || p25CC || nxdnCC) {
m_control = true;
setText("CONTROL");
m_tbText = std::string("CONTROL");
}
// if we aren't a dedicated control channel; set our
// title bar appropriately and set Tx state
if (!m_control) {
if (dmrTSCCEnable || p25CtrlEnable || nxdnCtrlEnable) {
setText("ENH. VOICE/CONV");
m_tbText = std::string("ENH. VOICE/CONV");
}
else {
setText("VOICE/CONV");
m_tbText = std::string("VOICE/CONV");
}
// are we transmitting?
@ -389,12 +471,12 @@ private:
// report last known transmitted destination ID
if (rsp["lastDstId"].is<uint32_t>()) {
uint32_t lastDstId = rsp["lastDstId"].get<uint32_t>();
if (lastDstId == 0) {
m_lastDst.setText("None");
}
else {
m_lastDst.setText(__INT_STR(lastDstId));
}
// pad TGs properly
std::ostringstream tgidOss;
tgidOss << std::setw(5) << std::setfill('0') << lastDstId;
m_lastDst.setText(tgidOss.str());
}
else {
::LogWarning(LOG_HOST, "%s:%u, does not report last TG information");
@ -403,12 +485,7 @@ private:
// report last known transmitted source ID
if (rsp["lastSrcId"].is<uint32_t>()) {
uint32_t lastSrcId = rsp["lastSrcId"].get<uint32_t>();
if (lastSrcId == 0) {
m_lastSrc.setText("None");
}
else {
m_lastSrc.setText(__INT_STR(lastSrcId));
}
m_lastSrc.setText(__INT_STR(lastSrcId));
}
else {
::LogWarning(LOG_HOST, "%s:%u, does not report last source information");
@ -434,7 +511,7 @@ private:
if (ret == network::rest::http::HTTPPayload::StatusType::OK) {
m_failed = false;
m_failCnt = 0U;
setText("UNKNOWN");
m_tbText = std::string("UNKNOWN");
}
}

@ -44,7 +44,16 @@ public:
* @brief Initializes a new instance of the NodeStatusWidget class.
* @param widget
*/
explicit NodeStatusWidget(FWidget* widget = nullptr) : FWidget{widget}
explicit NodeStatusWidget(FWidget* widget = nullptr) : FWidget{widget},
chData(),
channelId(0U),
channelNo(0U),
peerId(0U),
uniqueId(0U),
peerStatus(),
m_failed(false),
m_control(false),
m_tx(false)
{
/* stub */
}
@ -150,17 +159,17 @@ public:
// are we a dedicated control channel?
if (dmrCC || p25CC || nxdnCC) {
m_control = true;
tbText = "CONTROL";
m_tbText = std::string("CONTROL");
}
// if we aren't a dedicated control channel; set our
// title bar appropriately and set Tx state
if (!m_control) {
if (dmrTSCCEnable || p25CtrlEnable || nxdnCtrlEnable) {
tbText = "ENH. VOICE/CONV";
m_tbText = std::string("ENH. VOICE/CONV");
}
else {
tbText = "VOICE/CONV";
m_tbText = std::string("VOICE/CONV");
}
// are we transmitting?
@ -172,8 +181,6 @@ public:
}
}
}
redraw();
}
private:
@ -181,7 +188,7 @@ private:
bool m_control;
bool m_tx;
FString tbText{}; // title bar text
FString m_tbText{}; // title bar text
FLabel m_modeStr{this};
FLabel m_peerIdStr{this};
@ -207,7 +214,10 @@ private:
{
setSize(FSize{NODE_STATUS_WIDTH, NODE_STATUS_HEIGHT});
tbText = "UNKNOWN";
setFocusable(false);
m_failed = true;
m_tbText = "UNKNOWN";
initControls();
}
@ -223,16 +233,8 @@ private:
setForegroundColor(wc->dialog_fg);
setBackgroundColor(wc->dialog_bg);
if (FVTerm::getFOutput()->isMonochron())
setReverse(true);
drawTitleBar();
setCursorPos({2, int(getHeight()) - 1});
if (FVTerm::getFOutput()->isMonochron())
setReverse(false);
if (m_failed) {
m_tbText = "FAILED";
setColor(FColor::LightGray, FColor::LightRed);
}
else if (m_control) {
@ -245,7 +247,16 @@ private:
setColor(FColor::LightGray, FColor::Black);
}
finalcut::drawBorder(this, FRect(FPoint{1, 2}, FPoint{NODE_STATUS_WIDTH, NODE_STATUS_HEIGHT}));
finalcut::drawBorder(this, FRect(FPoint{1, 1}, FPoint{NODE_STATUS_WIDTH, NODE_STATUS_HEIGHT + 1}));
if (FVTerm::getFOutput()->isMonochron())
setReverse(true);
drawTitleBar();
setCursorPos({2, int(getHeight()) - 1});
if (FVTerm::getFOutput()->isMonochron())
setReverse(false);
}
/**
@ -253,7 +264,7 @@ private:
*/
void drawTitleBar()
{
print() << FPoint{1, 1};
print() << FPoint{2, 1};
// Fill with spaces (left of the title)
if (FVTerm::getFOutput()->getMaxColor() < 16)
@ -276,30 +287,30 @@ private:
}
const auto width = getWidth();
auto textWidth = getColumnWidth(tbText);
auto textWidth = getColumnWidth(m_tbText);
std::size_t leadingSpace{0};
if (width > textWidth)
leadingSpace = (width - textWidth) / 2;
leadingSpace = ((width - textWidth) / 2) - 1;
// Print leading whitespace
print(FString(leadingSpace, L' '));
// Print title bar text
if (!tbText.isEmpty()) {
if (!m_tbText.isEmpty()) {
if (textWidth <= width)
print(tbText);
print(m_tbText);
else {
// Print ellipsis
const auto len = getLengthFromColumnWidth(tbText, width - 2);
print(tbText.left(len));
const auto len = getLengthFromColumnWidth(m_tbText, width - 2);
print(m_tbText.left(len));
print("..");
textWidth = len + 2;
}
}
// Print trailing whitespace
std::size_t trailingSpace = width - leadingSpace - textWidth;
std::size_t trailingSpace = (width - leadingSpace - textWidth) - 2;
print(FString(trailingSpace, L' '));
if (FVTerm::getFOutput()->getMaxColor() < 16)
@ -316,28 +327,28 @@ private:
// in this widget...so we're forcing them to LightGray, this will be a problem if the overall palette
// changes in the future.
m_modeStr.setGeometry(FPoint(24, 3), FSize(4, 1));
m_modeStr.setGeometry(FPoint(24, 2), FSize(4, 1));
m_modeStr.setAlignment(Align::Right);
m_modeStr.setForegroundColor(FColor::DarkBlue); // why?
m_modeStr.setBackgroundColor(FColor::LightGray); // why?
m_peerIdStr.setGeometry(FPoint(19, 4), FSize(9, 1));
m_peerIdStr.setGeometry(FPoint(19, 3), FSize(9, 1));
m_peerIdStr.setForegroundColor(FColor::DarkBlue); // why?
m_peerIdStr.setBackgroundColor(FColor::LightGray); // why?
m_peerIdStr.setAlignment(Align::Right);
m_peerIdentityStr.setGeometry(FPoint(19, 5), FSize(9, 1));
m_peerIdentityStr.setGeometry(FPoint(19, 4), FSize(9, 1));
m_peerIdentityStr.setForegroundColor(FColor::DarkBlue); // why?
m_peerIdentityStr.setBackgroundColor(FColor::LightGray); // why?
m_peerIdentityStr.setAlignment(Align::Right);
// channel number
{
m_channelNoLabel.setGeometry(FPoint(2, 3), FSize(10, 1));
m_channelNoLabel.setGeometry(FPoint(2, 2), FSize(10, 1));
m_channelNoLabel.setForegroundColor(FColor::Black); // why?
m_channelNoLabel.setBackgroundColor(FColor::LightGray); // why?
m_chanNo.setGeometry(FPoint(11, 3), FSize(8, 1));
m_chanNo.setGeometry(FPoint(11, 2), FSize(8, 1));
m_chanNo.setForegroundColor(FColor::Black); // why?
m_chanNo.setBackgroundColor(FColor::LightGray); // why?
m_chanNo.setText("");
@ -345,18 +356,18 @@ private:
// channel frequency
{
m_txFreqLabel.setGeometry(FPoint(2, 4), FSize(4, 1));
m_txFreqLabel.setGeometry(FPoint(2, 3), FSize(4, 1));
m_txFreqLabel.setForegroundColor(FColor::Black); // why?
m_txFreqLabel.setBackgroundColor(FColor::LightGray); // why?
m_txFreq.setGeometry(FPoint(6, 4), FSize(9, 1));
m_txFreq.setGeometry(FPoint(6, 3), FSize(9, 1));
m_txFreq.setForegroundColor(FColor::Black); // why?
m_txFreq.setBackgroundColor(FColor::LightGray); // why?
m_txFreq.setText("");
m_rxFreqLabel.setGeometry(FPoint(2, 5), FSize(4, 1));
m_rxFreqLabel.setGeometry(FPoint(2, 4), FSize(4, 1));
m_rxFreqLabel.setForegroundColor(FColor::Black); // why?
m_rxFreqLabel.setBackgroundColor(FColor::LightGray); // why?
m_rxFreq.setGeometry(FPoint(6, 5), FSize(9, 1));
m_rxFreq.setGeometry(FPoint(6, 4), FSize(9, 1));
m_rxFreq.setForegroundColor(FColor::Black); // why?
m_rxFreq.setBackgroundColor(FColor::LightGray); // why?
m_rxFreq.setText("");
@ -402,9 +413,24 @@ public:
* @brief Initializes a new instance of the ScrollView class.
* @param widget
*/
explicit ScrollView(finalcut::FWidget* widget = nullptr) : finalcut::FScrollView{widget}
explicit ScrollView(finalcut::FWidget* widget = nullptr) : finalcut::FScrollView{widget},
m_nodes()
{
/* stub */
m_nodes.clear();
}
/**
* @brief
*/
void deinit()
{
// deinitialize the node widgets
for (auto entry : m_nodes) {
entry->removeParent();
delete entry;
entry = nullptr;
}
m_nodes.clear();
}
/**
@ -591,8 +617,8 @@ private:
std::vector<NodeStatusWidget*> m_nodes;
const int m_defaultOffsX = 2;
int m_nodeWdgtOffsX = m_defaultOffsX;
int m_nodeWdgtOffsY = 2;
int m_nodeWdgtOffsX = 2;
int m_nodeWdgtOffsY = 1;
/**
* @brief Initializes the window layout.
@ -600,6 +626,9 @@ private:
void initLayout() override
{
FScrollView::initLayout();
setFlags().feature.no_border = true;
setHorizontalScrollBarMode(ScrollBarMode::Hidden);
}
/**
@ -651,9 +680,11 @@ private:
// update widget status
try
{
wdgt->setFailed(false);
wdgt->update();
}
catch (std::exception& e) {
wdgt->setFailed(true);
::LogWarning(LOG_HOST, "PEER %u, failed to update peer status, %s", peerId, e.what());
}
@ -669,9 +700,6 @@ private:
wdgt->redraw();
m_nodes.push_back(wdgt);
rootWidget->redraw();
redraw();
}
/**
@ -685,6 +713,8 @@ private:
{
assert(wdgt != nullptr);
const auto& rootWidget = getRootWidget();
uint8_t channelId = peerObj["channelId"].get<uint8_t>();
uint32_t channelNo = peerObj["channelNo"].get<uint32_t>();
@ -730,14 +760,16 @@ public:
* @brief Initializes a new instance of the NodeStatusWnd class.
* @param widget
*/
explicit NodeStatusWnd(FWidget* widget = nullptr) : FDialog{widget}
explicit NodeStatusWnd(FWidget* widget = nullptr) : FDialog{widget},
m_killed(false),
m_threadStopped(false)
{
m_killed = false;
Thread::runAsThread(this, threadNodeUpdate);
}
private:
bool m_killed;
bool m_threadStopped;
ScrollView m_scroll{this};
@ -750,6 +782,7 @@ private:
FDialog::setSize(FSize{80, 25});
FDialog::setMinimizable(false);
FDialog::setResizeable(false);
FDialog::setShadow();
std::size_t maxWidth, maxHeight;
@ -788,7 +821,7 @@ private:
void initControls()
{
m_scroll.setGeometry(FPoint{1, 1}, FSize{78, 22});
m_scroll.setScrollSize(FSize{230, 440});
m_scroll.setScrollSize(FSize{440, 440});
m_scroll.update();
}
@ -798,7 +831,7 @@ private:
*/
void adjustSize() override
{
m_scroll.setGeometry(FPoint{1, 1}, FSize{getWidth() - 2, getHeight() - 3});
m_scroll.setGeometry(FPoint{1, 1}, FSize{getWidth() - 1, getHeight() - 2});
}
/* Entry point to node update thread. */
@ -840,12 +873,13 @@ private:
killed = wnd->m_killed;
}
Thread::sleep(250U);
Thread::sleep(175U);
} else {
break;
}
}
wnd->m_threadStopped = true;
LogDebug(LOG_HOST, "[STOP] %s", threadName.c_str());
delete th;
}
@ -876,8 +910,11 @@ private:
void onClose(FCloseEvent* e) override
{
m_killed = true;
Thread::sleep(1250U); // this is a horrible way of making sure the update thread stops...
while (!m_threadStopped) {
Thread::sleep(125U);
}
m_scroll.deinit();
hide();
}
};

Loading…
Cancel
Save

Powered by TurnKey Linux.