10 #include <fmt/format.h> 38 , m_fdWatcher(fdWatcher)
90 fdWatcher->registerFD(STDIN_FILENO, boost::bind(&
UI::readInput,
this));
103 for(
int i = 0; i < n; ++i)
105 float hue = i * 360 / n;
117 std::min(255, std::max(0, static_cast<int>(r)))
118 | (std::min(255, std::max(0, static_cast<int>(g))) << 8)
119 | (std::min(255, std::max(0, static_cast<int>(b))) << 16);
131 constexpr
unsigned int column()
const 134 template<
typename ... Args>
135 void operator()(Args&& ... args)
137 std::string str = fmt::format(std::forward<Args>(args)...);
139 fputs(str.c_str(), stdout);
148 std::string fullName;
150 fullName = node.
name();
155 if(!fullName.empty() && fullName[0] ==
'/')
156 fullName = fullName.substr(1);
158 return fullName.substr(0, maxWidth);
163 const int NODE_WIDTH = 13;
165 unsigned int lines = 0;
186 auto printKey = [&](
const std::string& key,
const std::string& label) {
190 print(
" {} ", label);
205 switch(selectedNode->state())
211 default: state =
"<UNKNOWN>";
break;
214 print(
"Node '{}' {}. Actions: ", selectedNode->fullName(),
state);
215 printKey(
"s",
"start");
216 printKey(
"k",
"stop");
217 printKey(
"d",
"debug");
219 if(selectedNode->isMuted())
220 printKey(
"u",
"unmute");
222 printKey(
"m",
"mute");
226 printKey(
"A-Z",
"Node actions");
227 printKey(
"F6",
"Start all");
228 printKey(
"F7",
"Stop all");
229 printKey(
"F8",
"Toggle WARN+ only");
230 printKey(
"F9",
"Mute all");
231 printKey(
"F10",
"Unmute all");
232 printKey(
"/",
"Node search");
239 print(
"! WARN+ output only !");
248 print(
"! Caution: Nodes muted !");
253 for(
int i = print.column(); i <
m_columns; ++i)
271 constexpr
auto SEARCH_NODE_WIDTH = NODE_WIDTH+3;
273 std::size_t nodeWidth = SEARCH_NODE_WIDTH;
275 nodeWidth = std::max(nodeWidth,
nodeDisplayName(*nodes[nodeIdx]).length());
278 if(m_searchNodes.size() * (nodeWidth+1) >= static_cast<std::size_t>(
m_columns-1))
279 nodeWidth = SEARCH_NODE_WIDTH;
281 const int BLOCK_WIDTH = nodeWidth;
282 for(
auto& nodeIdx : m_searchNodes)
292 fmt::print(
"{:^{}}", label, nodeWidth);
303 else if(col + 1 + BLOCK_WIDTH >
m_columns)
331 fmt::print(
"{:c}", key);
341 switch(node->state())
359 switch(node->state())
378 fmt::print(
"[{:^{}}]", label, NODE_WIDTH);
380 fmt::print(
" {:^{}} ", label, NODE_WIDTH);
384 const int BLOCK_WIDTH = NODE_WIDTH + 3;
392 else if(col + 1 + BLOCK_WIDTH >
m_columns)
417 g_statusLines = std::max(lines, g_statusLines);
431 const std::string&
clean =
event.message;
440 auto actualLabelWidth = std::max<unsigned int>(
m_nodeLabelWidth,
event.source.size());
441 auto lines = it->second.parser.wrap(clean,
m_columns - actualLabelWidth - 2);
443 for(
unsigned int line = 0; line < lines.size(); ++line)
460 fmt::print(
"{:>{}}:", event.
source, m_nodeLabelWidth);
463 for(
unsigned int i = 0; i < actualLabelWidth-1; ++i)
471 fputs(lines[line].c_str(), stdout);
484 unsigned int len = clean.length();
485 while(len != 0 && (clean[len-1] ==
'\n' || clean[len-1] ==
'\r'))
501 fwrite(clean.c_str(), 1, len, stdout);
548 w = std::max(w, node->fullName().size());
636 if(row < numRows - 1)
647 else if(std::isgraph(c))
655 for(
unsigned int i = 0; i < nodes.size(); ++i)
657 const auto& node = nodes[i];
659 if(idx != std::string::npos)
713 if(c >=
'a' && c <=
'z')
715 else if(c >=
'A' && c <=
'Z')
716 nodeIndex = 26 + c -
'A';
717 else if(c >=
'0' && c <=
'9')
718 nodeIndex = 26 + 26 + c -
'0';
720 if(nodeIndex < 0 || (
size_t)nodeIndex >=
m_monitor->
nodes().size())
738 node->launchDebugger();
741 node->setMuted(
true);
744 node->setMuted(
false);
const std::vector< NodeMonitor::Ptr > & nodes() const
boost::signals2::signal< void(LogEvent)> logMessageSignal
std::map< std::string, ChannelInfo > m_nodeColorMap
bool getSize(int *columns, int *rows)
Get current window size.
std::string m_searchString
Monitors a single node process.
void setSimpleBackground(SimpleColor color)
void moveCursorToStartOfLine()
Move cursor to start of the line.
std::string nodeDisplayName(monitor::NodeMonitor &node, std::size_t maxWidth=std::string::npos)
Color color(SimpleColor code)
FDWatcher::Ptr m_fdWatcher
void setBackgroundColor(uint32_t color)
Set 24-bit background color.
UI(monitor::Monitor *monitor, const FDWatcher::Ptr &fdWatcher)
Terminal::Style m_style_nodeIdle
Terminal::Style m_style_barLine
ROSCPP_DECL std::string clean(const std::string &name)
Terminal::Style m_style_nodeWaitingFaded
unsigned int m_searchSelectedIndex
monitor::Monitor * m_monitor
ROSCONSOLE_DECL void print(FilterBase *filter, void *logger, Level level, const char *file, int line, const char *function, const char *fmt,...) ROSCONSOLE_PRINTF_ATTRIBUTE(7
void setSimplePair(SimpleColor fg, SimpleColor bg)
Terminal::Style m_style_nodeCrashed
ros::WallTimer m_sizeTimer
Idle (e.g. exited with code 0)
std::string namespaceString() const
Node namespace.
Terminal::Style m_style_nodeWaiting
void HUSLtoRGB(float *r, float *g, float *b, float h, float s, float l)
Terminal::Style m_style_nodeIdleFaded
void setLineWrap(bool on)
void clearToEndOfLine()
Clear characters from cursor to end of line.
static std::string g_windowTitle
Terminal::Style m_style_nodeRunningFaded
unsigned int m_nodeLabelWidth
Terminal::Style m_style_bar
Terminal::Style m_style_nodeKeyMuted
Terminal::Style m_style_nodeKey
std::vector< unsigned int > m_searchNodes
void setStandardColors()
Reset fg + bg to standard terminal colors.
Waiting for automatic restart after crash.
Terminal::Color m_color_bar
static unsigned int g_statusLines
void setCursorVisible()
restore cursor
void setSimpleForeground(SimpleColor color)
Encapsulates terminal control.
void moveCursorUp(int numLines)
Move cursor up by numLines.
bool has256Colors() const
void setWindowTitle(const std::string &title)
void log(const LogEvent &event)
Terminal::Style m_style_nodeRunning
void setCursorInvisible()
hide cursor
Terminal::Style m_style_barKey
Crashed (i.e. exited with code != 0)
launch::LaunchConfig::ConstPtr config() const
unsigned int m_searchDisplayColumns
ros::WallTimer m_terminalCheckTimer
std::string name() const
Node name.
void clearWindowTitle(const std::string &backup)
Terminal::Style m_style_nodeCrashedFaded
Terminal::Style m_style_barHighlight
std::shared_ptr< NodeMonitor > Ptr