| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /* 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_NEXT_LINE);
- form_driver(this->Form, REQ_BEG_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];
- snprintf(vertmp, sizeof(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];
- snprintf(firstLine, sizeof(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_NEXT_LINE);
- form_driver(this->Form, REQ_BEG_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();
- #ifdef _WIN32
- if (key == KEY_RESIZE) {
- HandleResize();
- }
- #endif // _WIN32
- snprintf(debugMessage, sizeof(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') || key == 'j') {
- form_driver(this->Form, REQ_SCR_FLINE);
- } else if (key == KEY_UP || key == ctrl('p') || key == 'k') {
- 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);
- }
- }
|