kNCurses/DemoApp.cpp
Christian Burger 3be5336ca0 refactoring tiling window manager
Laying out the windows in the window manager frame, is a very similar
process regardless of doing it horizontally or vertically. So the
template design pattern was applied and the general functionality was
pulled up; only specific functionalities were put into the corresponding
classes.

kNCursesDemoApp: Separated the screen into three windows vertically. The
top and bottom window contain another two windows each, lay out
horizontally. The top left window is fixed to width 1 and the top right
takes the rest of the space. Bottom two windows take 50 % of the space
each.

Remarks: There are still some rendering bugs, when hiding and showing
windows. E. g. when hiding the top or middle window with `<F1>` or
`<F2>` respectively, the bottom window has some errors. Maybe some
timing issue.
2022-05-18 21:15:13 +02:00

143 lines
4.8 KiB
C++

/**
* @author Christian Burger (christian@krikkel.de)
*/
#include "DemoApp.hpp"
#include "Debug.hpp"
#include <kNCurses/VerticalTilingWindowManager.hpp>
#include <kNCurses/HorizontalTilingWindowManager.hpp>
#include <kNCurses/Window.hpp>
#include <kNCurses/PtyWindow.hpp>
#include <unistd.h>
#include <utmp.h>
#include <cstdlib>
namespace krikkel::NCurses
{
using std::scoped_lock;
DemoApp::DemoApp() : NCursesApplication(false)
{
}
int DemoApp::run()
{
setUpWindows();
forkShell();
mainLoop();
return 0;
}
void DemoApp::setUpWindows()
{
windowManager
= new VerticalTilingWindowManager(Root_Window, &ncursesMutex);
topWindowManager
= new HorizontalTilingWindowManager(new Window(), &ncursesMutex);
bottomWindowManager
= new HorizontalTilingWindowManager(new Window(), &ncursesMutex);
windowManager->addWindow(topWindowManager);
ptyWindow = new PtyWindow(&ncursesMutex, 0, 0, 0, 0);
windowManager->addWindow(ptyWindow);
windowManager->addWindow(bottomWindowManager);
windowManager->updateLayout();
windowManager->refresh();
dummyWindowTopLeft = new Window();
topWindowManager->addWindow(dummyWindowTopLeft, 1);
dummyWindowTopLeft->addstr("t\no\np\n \nl\ne\nf\nt\n w\ni\nn\nd\no\nw");
dummyWindowTopRight = new Window(topWindowManager);
dummyWindowTopRight->addstr("top right window");
topWindowManager->updateLayout();
topWindowManager->refresh();
dummyWindowBottomLeft = new Window(bottomWindowManager);
dummyWindowBottomLeft->addstr("bottom left window");
dummyWindowBottomRight = new Window(bottomWindowManager);
dummyWindowBottomRight->addstr("bottom right window");
bottomWindowManager->updateLayout();
bottomWindowManager->refresh();
}
void DemoApp::forkShell()
{
if(fork() == 0)
{
const char *shellPath = getenv("SHELL");
if(!shellPath)
shellPath = "/bin/bash";
login_tty(ptyWindow->getFdPtyClient());
const int sizeArg = 2;
const char *arg[sizeArg] = {shellPath, NULL};
fprintf(stderr, "<CTRL>+C exits shell.\n\n");
execv(shellPath, const_cast<char * const *>(arg));
fprintf(stderr, "Well, well, well … could not start a shell. We "
"tried `%s`. Maybe set `SHELL` environment variable"
" to a working value?", shellPath);
exit(1);
}
}
void DemoApp::mainLoop()
{
while(true)
{
SingleUserInput input = windowManager->readSingleUserInput();
if(input.isNormalKey())
{
ptyWindow->writeUnicodeCharToClient(input.getRawInput());
{
scoped_lock lock(ncursesMutex);
dummyWindowTopRight->addch(input.getRawInput());
dummyWindowTopRight->refresh();
}
}
if(input.isFunctionKey())
{
switch(input.getRawInput())
{
case KEY_RESIZE:
windowManager->updateLayout();
break;
case KEY_F(1):
if(topWindowManager->isHidden())
windowManager->showWindow(topWindowManager);
else
windowManager->hideWindow(topWindowManager);
windowManager->updateLayout();
windowManager->refresh();
break;
case KEY_F(2):
if(ptyWindow->isHidden())
windowManager->showWindow(ptyWindow);
else
windowManager->hideWindow(ptyWindow);
windowManager->updateLayout();
windowManager->refresh();
break;
case KEY_F(3):
if(bottomWindowManager->isHidden())
windowManager->showWindow(bottomWindowManager);
else
windowManager->hideWindow(bottomWindowManager);
windowManager->updateLayout();
windowManager->refresh();
break;
case KEY_F(5):
windowManager->refresh();
break;
default:
ptyWindow->writeFunctionKeyToClient(input.mapKeyNcursesToVTerm());
}
}
}
}
}