diff options
Diffstat (limited to 'Source/CursesDialog/cmCursesLongMessageForm.cxx')
-rw-r--r-- | Source/CursesDialog/cmCursesLongMessageForm.cxx | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx new file mode 100644 index 0000000..591c546 --- /dev/null +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -0,0 +1,200 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCursesLongMessageForm.h" + +#include <cstdio> +#include <cstring> + +#include "cmCursesForm.h" +#include "cmCursesMainForm.h" +#include "cmCursesStandardIncludes.h" +#include "cmStringAlgorithms.h" +#include "cmVersion.h" + +inline int ctrl(int z) +{ + return (z & 037); +} + +cmCursesLongMessageForm::cmCursesLongMessageForm( + std::vector<std::string> const& messages, const char* title, + ScrollBehavior scrollBehavior) + : Scrolling(scrollBehavior) +{ + // Append all messages into on big string + this->Messages = cmJoin(messages, "\n"); + this->Title = title; + this->Fields[0] = nullptr; + this->Fields[1] = nullptr; +} + +cmCursesLongMessageForm::~cmCursesLongMessageForm() +{ + if (this->Fields[0]) { + free_field(this->Fields[0]); + } +} + +void cmCursesLongMessageForm::UpdateContent(std::string const& output, + std::string const& title) +{ + this->Title = title; + + if (!output.empty() && this->Messages.size() < MAX_CONTENT_SIZE) { + this->Messages.push_back('\n'); + this->Messages.append(output); + form_driver(this->Form, REQ_NEW_LINE); + this->DrawMessage(output.c_str()); + } + + this->UpdateStatusBar(); + touchwin(stdscr); + refresh(); +} + +void cmCursesLongMessageForm::UpdateStatusBar() +{ + int x; + int y; + getmaxyx(stdscr, y, x); + + char bar[cmCursesMainForm::MAX_WIDTH]; + size_t size = this->Title.size(); + if (size >= cmCursesMainForm::MAX_WIDTH) { + size = cmCursesMainForm::MAX_WIDTH - 1; + } + strncpy(bar, this->Title.c_str(), size); + for (size_t i = size; i < cmCursesMainForm::MAX_WIDTH; i++) { + bar[i] = ' '; + } + int width; + if (x >= 0 && x < cmCursesMainForm::MAX_WIDTH) { + width = x; + } else { + width = cmCursesMainForm::MAX_WIDTH - 1; + } + + bar[width] = '\0'; + + char version[cmCursesMainForm::MAX_WIDTH]; + char vertmp[128]; + sprintf(vertmp, "CMake Version %s", cmVersion::GetCMakeVersion()); + size_t sideSpace = (width - strlen(vertmp)); + for (size_t i = 0; i < sideSpace; i++) { + version[i] = ' '; + } + sprintf(version + sideSpace, "%s", vertmp); + version[width] = '\0'; + + char fmt_s[] = "%s"; + curses_move(y - 4, 0); + attron(A_STANDOUT); + printw(fmt_s, bar); + attroff(A_STANDOUT); + curses_move(y - 3, 0); + printw(fmt_s, version); + pos_form_cursor(this->Form); +} + +void cmCursesLongMessageForm::PrintKeys() +{ + int x; + int y; + getmaxyx(stdscr, y, x); + if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) { + return; + } + char firstLine[512]; + sprintf(firstLine, "Press [e] to exit screen"); + + char fmt_s[] = "%s"; + curses_move(y - 2, 0); + printw(fmt_s, firstLine); + pos_form_cursor(this->Form); +} + +void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/, + int /*height*/) +{ + int x; + int y; + getmaxyx(stdscr, y, x); + + if (this->Form) { + unpost_form(this->Form); + free_form(this->Form); + this->Form = nullptr; + } + + if (this->Fields[0]) { + free_field(this->Fields[0]); + this->Fields[0] = nullptr; + } + + this->Fields[0] = new_field(y - 6, x - 2, 1, 1, 0, 0); + + field_opts_off(this->Fields[0], O_STATIC); + + this->Form = new_form(this->Fields); + post_form(this->Form); + + form_driver(this->Form, REQ_BEG_FIELD); + this->DrawMessage(this->Messages.c_str()); + + this->UpdateStatusBar(); + touchwin(stdscr); + refresh(); +} + +void cmCursesLongMessageForm::DrawMessage(const char* msg) const +{ + int i = 0; + while (msg[i] != '\0' && i < MAX_CONTENT_SIZE) { + if (msg[i] == '\n' && msg[i + 1] != '\0') { + form_driver(this->Form, REQ_NEW_LINE); + } else { + form_driver(this->Form, msg[i]); + } + i++; + } + if (this->Scrolling == ScrollBehavior::ScrollDown) { + form_driver(this->Form, REQ_END_FIELD); + } else { + form_driver(this->Form, REQ_BEG_FIELD); + } +} + +void cmCursesLongMessageForm::HandleInput() +{ + if (!this->Form) { + return; + } + + char debugMessage[128]; + + for (;;) { + this->PrintKeys(); + int key = getch(); + + sprintf(debugMessage, "Message widget handling input, key: %d", key); + cmCursesForm::LogMessage(debugMessage); + + // quit + if (key == 'o' || key == 'e') { + break; + } + if (key == KEY_DOWN || key == ctrl('n')) { + form_driver(this->Form, REQ_SCR_FLINE); + } else if (key == KEY_UP || key == ctrl('p')) { + form_driver(this->Form, REQ_SCR_BLINE); + } else if (key == KEY_NPAGE || key == ctrl('d')) { + form_driver(this->Form, REQ_SCR_FPAGE); + } else if (key == KEY_PPAGE || key == ctrl('u')) { + form_driver(this->Form, REQ_SCR_BPAGE); + } + + this->UpdateStatusBar(); + touchwin(stdscr); + wrefresh(stdscr); + } +} |