2022-05-03 11:23:32 +02:00
|
|
|
/**
|
|
|
|
* @author Christian Burger (christian@krikkel.de)
|
|
|
|
*/
|
|
|
|
|
2022-05-06 22:42:09 +02:00
|
|
|
#include <kNCurses/VerticalTilingWindowManager.hpp>
|
|
|
|
#include <kNCurses/Window.hpp>
|
2022-05-03 11:23:32 +02:00
|
|
|
#include <ncursesw/ncurses.h>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace krikkel::NCurses
|
|
|
|
{
|
|
|
|
using std::list;
|
2022-05-06 14:02:18 +02:00
|
|
|
using std::recursive_mutex;
|
2022-05-06 18:37:48 +02:00
|
|
|
using std::scoped_lock;
|
2022-05-03 11:23:32 +02:00
|
|
|
using std::find;
|
|
|
|
|
2022-05-06 14:02:18 +02:00
|
|
|
VerticalTilingWindowManager::VerticalTilingWindowManager(NCursesWindow *rootWindow, recursive_mutex *ncursesMutex)
|
|
|
|
: rootWindow(new Window(*rootWindow)), ncursesMutex(ncursesMutex)
|
2022-05-03 11:23:32 +02:00
|
|
|
{}
|
|
|
|
|
|
|
|
void VerticalTilingWindowManager::addWindow(Window *window)
|
|
|
|
{
|
|
|
|
stack.push_back(window);
|
2022-05-06 14:02:18 +02:00
|
|
|
visibleStack.push_back(window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VerticalTilingWindowManager::hideWindow(Window *window)
|
|
|
|
{
|
|
|
|
visibleStack.remove(window);
|
|
|
|
window->hidden = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VerticalTilingWindowManager::showWindow(Window *window)
|
|
|
|
{
|
|
|
|
if(!window->hidden)
|
|
|
|
return;
|
|
|
|
|
|
|
|
list<Window *>::iterator currentVisibleWindow = visibleStack.begin();
|
|
|
|
for(Window *currentWindow : stack)
|
|
|
|
{
|
|
|
|
if(currentWindow == window)
|
|
|
|
{
|
|
|
|
visibleStack.insert(currentVisibleWindow, window);
|
|
|
|
window->hidden = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(currentWindow != (*currentVisibleWindow))
|
|
|
|
continue;
|
|
|
|
++currentVisibleWindow;
|
|
|
|
}
|
2022-05-03 11:23:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void VerticalTilingWindowManager::refresh()
|
|
|
|
{
|
2022-05-06 18:37:48 +02:00
|
|
|
scoped_lock lock(*ncursesMutex);
|
2022-05-06 14:02:18 +02:00
|
|
|
|
2022-05-03 11:23:32 +02:00
|
|
|
rootWindow->refresh();
|
2022-05-06 14:02:18 +02:00
|
|
|
for(Window *window : visibleStack)
|
2022-05-03 11:23:32 +02:00
|
|
|
window->refresh();
|
|
|
|
}
|
|
|
|
|
2022-05-06 14:02:18 +02:00
|
|
|
SingleUserInput VerticalTilingWindowManager::readSingleUserInput()
|
|
|
|
{
|
|
|
|
return rootWindow->readSingleUserInput();
|
|
|
|
}
|
|
|
|
|
2022-05-03 11:23:32 +02:00
|
|
|
void VerticalTilingWindowManager::updateLayout()
|
|
|
|
{
|
2022-05-06 22:15:34 +02:00
|
|
|
size_t stackSize = visibleStack.size();
|
|
|
|
if(stackSize == 0)
|
|
|
|
{
|
|
|
|
rootWindow->clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-06 18:37:48 +02:00
|
|
|
scoped_lock lock(*ncursesMutex);
|
2022-05-03 11:23:32 +02:00
|
|
|
int availableWidth = rootWindow->width();
|
|
|
|
int availableHeight = rootWindow->height();
|
2022-05-06 14:02:18 +02:00
|
|
|
int windowHeight = availableHeight / stackSize - 1;
|
|
|
|
|
|
|
|
if((windowHeight + 1) * stackSize < availableHeight)
|
2022-05-03 11:23:32 +02:00
|
|
|
++windowHeight;
|
|
|
|
|
|
|
|
uint16_t y = 0;
|
2022-05-06 14:02:18 +02:00
|
|
|
list<Window *>::iterator it = visibleStack.begin();
|
2022-05-03 11:23:32 +02:00
|
|
|
for(size_t index = 0
|
2022-05-06 14:02:18 +02:00
|
|
|
; index < visibleStack.size() - 1
|
2022-05-03 11:23:32 +02:00
|
|
|
; ++index)
|
|
|
|
{
|
|
|
|
resizeWindowInStack(*it++, y, windowHeight, availableWidth);
|
|
|
|
y += windowHeight;
|
|
|
|
{
|
|
|
|
rootWindow->move(y++, 0);
|
|
|
|
rootWindow->hline(availableWidth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
resizeWindowInStack(*it, y, availableHeight - y, availableWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VerticalTilingWindowManager::resizeWindowInStack(Window *window, uint16_t y, uint16_t height, uint16_t width)
|
|
|
|
{
|
|
|
|
window->resize(height, width);
|
|
|
|
window->mvwin(y, 0);
|
|
|
|
}
|
|
|
|
}
|