From time to time looking through the topics in the Habré, I constantly find myself thinking that even a little bit and some neural interface in a laptop will become a reality. In my work, I constantly come across the fact that modern people do not really understand and love a simple command line. And reading them manuals is all the more lazy.
But in my practice it often happens that you need a small utility that performs one or two functions. And where exactly it will be executed is unknown. It can be Windows, it can be exclusively terminal Linux, boot media - whatever. I'm not a programmer, but sometimes you need to make life easier for yourself or others. And preferably as clearly as possible. At first I tried to do just console utilities. Actually, from this, probably, everything begins. But it quickly turned out that using printf / sprintf / puts and other tools (and I write in C) it is not very convenient to format the text, display some information. A window with a constant “scrolling” does not look very nice, and if there is a lot of information, it is completely unreadable. Then I remembered ncurses.

Usually curses / ncurses is associated with Linux, although in fact there are compatible implementations for many platforms, in particular under Windows. Initially, most of the utilities were needed under Win, and I did not know any graphical frameworks and desperately looked for ways to properly format the text, make it beautifully and visually. That's when I came across a
Public Domain Curses . Designed to be compatible with ncurses, it allows you to write cross-platform applications using most of the capabilities of the original curses / ncurses. But, unfortunately, no bugs and restrictions can not do. But it is not as scary as it seemed at first. I want to show that creating a console-friendly pseudo-window application that is pleasing to the eye is not so difficult; and at the exit we get a warm tube TUI. It would be desirable, that people did not forget about such methods of work with the user.
In this post, I will describe the work compatible with PDcurses, so these examples should be collected without problems and under Windows and under Linux.
Start
As we work with the text interface, the unit of dimension will be one character. You can work with both ordinary ASCII and Wide characters. It should be remembered that only that terminal can display curses. Unfortunately, personally, my 80% of pseudographics is not displayed adequately. Slightly better on Linux, really bad on Windows. Fortunately, simple lines are displayed normally.
We can work with windows, panels, colors and text (including scrolling, copying, etc.).
Before starting work, we need to get ready for work, turn on (not) the necessary options in (s).
This is what my usual start of work looks like. At first there was a window
When we start the emulator / instance of the terminal, we are in stdscr. This is our base, initial window. We can work in it or build our windows.
Enough words, let's get down to business. Create a window. Just want to note an important nuance - everywhere, in all functions, first goes Y, then X
')
WINDOW *win = newwin(height, width, y, x);
Each new window has its own relative coordinates, which you will operate with in the future. It is important and convenient.

The window was created, but nothing appeared in the console. Because the window inherits the attributes of the parent - stdscr in our case.
Immediately show how I do. There is a structure that describes the "virtual window", I will tell about the panels later
struct cursed_window { WINDOW *background; WINDOW *decoration; WINDOW *overlay; PANEL *panel; }; typedef struct cursed_window curw;
I do this in order to first make a design that will not change and which is static. We change only the working data, while not overwriting the design.
Window background - transparent background and shadow from the window.
decoration - frame, it is drawn automatically
overlay is the working field itself. The origin of it will be 0,0, since this is a new window, you do not need to amend the frame and the shadow.
about the panel - later.
Create our virtual window curw *tui_new_win(int sy, int sx, int h, int w, char *label) { curw *new = malloc (sizeof *new); new->background = newwin(h, w, sy, sx);

In fact, if we create a second window on top of this, then our background will “pull” on the bottom window. It's not beautiful. But disposable. But this is a topic for another conversation. Remove shadows for simplicity and create multiple windows.

And now we can say about the panel. A panel is a container stack containing a window and all its child windows. With the panel you can spend a lot of interesting manipulations.
Panels
Now you can demonstrate the capabilities of the panels in practice. The topmost window in the stack is available for default operation. We can also access any windows and panels in the stack below, write in them, without affecting the windows in the stack above. We can sort the windows ourselves whatever we want, move them, resize them. Sorry for the primitive code, but I tried to make it clearer.
Finally create the main loop. int x, y; getmaxyx(stdscr, y, x); curw *wins[3];
But the window moving routine void tui_move_panel(curw *win, int ch) { int begy, begx, maxx, maxy, x, y; getbegyx(panel_window(win->panel), begy, begx); getmaxyx(panel_window(win->panel), maxy, maxx); getmaxyx(stdscr, y, x); switch (ch) { case KEY_UP: if ((begy - 1) >= 0) begy--; break; case KEY_DOWN: if (((begy + 1) + maxy) <= y) begy++; break; case KEY_LEFT: if ((begx - 1) >= 0) begx--; break; case KEY_RIGHT: if (((begx + 1) + maxx) <= x) begx++; break; } move_panel(win->panel, begy, begx); }
Well, as a result

I thought of describing more, but apparently, it would have been too big and boring post, I just wanted to draw attention to this "ancient technology", which has enough features. Behind the frame there are manipulations with the text, with attributes and other things. For example, it is possible to copy a string of text from any window, find out its color and mode. And much more.
Hope this was not too boring.