added simple vertical tiling window manager
This commit is contained in:
parent
f8db9dc660
commit
0462a68c54
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -53,7 +53,8 @@
|
|||
"iostream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"pointers": "cpp"
|
||||
"pointers": "cpp",
|
||||
"list": "cpp"
|
||||
},
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||
"C_Cpp.default.includePath": [
|
||||
|
|
16
App.cpp
16
App.cpp
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "App.hpp"
|
||||
#include "Debug.hpp"
|
||||
#include <NCurses/VerticalTilingWindowManager.hpp>
|
||||
#include <NCurses/Window.hpp>
|
||||
#include <NCurses/PtyWindow.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -20,13 +22,15 @@ namespace krikkel::NCurses
|
|||
|
||||
int DemoApp::run()
|
||||
{
|
||||
std::mutex writeMutex;
|
||||
std::mutex ncursesMutex;
|
||||
VerticalTilingWindowManager windowManager(Root_Window, &ncursesMutex);
|
||||
|
||||
PtyWindow *ptyWindow = new PtyWindow(&writeMutex
|
||||
, Root_Window->lines()
|
||||
, Root_Window->cols()
|
||||
, 0
|
||||
, 0);
|
||||
new Window(&windowManager);
|
||||
PtyWindow *ptyWindow = new PtyWindow(&ncursesMutex, 0, 0, 0, 0);
|
||||
windowManager.addWindow(ptyWindow);
|
||||
new Window(&windowManager);
|
||||
windowManager.updateLayout();
|
||||
windowManager.refresh();
|
||||
|
||||
if(fork() == 0)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ set(CMAKE_CXX_STANDARD 17)
|
|||
include(CTest)
|
||||
enable_testing()
|
||||
|
||||
add_library(NCurses Window.cpp PtyWindow.cpp SingleUserInput.cpp Debug.cpp)
|
||||
add_library(NCurses Window.cpp PtyWindow.cpp SingleUserInput.cpp Debug.cpp VerticalTilingWindowManager.cpp)
|
||||
|
||||
### path to own system includes
|
||||
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/include")
|
||||
|
@ -44,7 +44,7 @@ target_link_libraries(NCursesDemoApp NCurses)
|
|||
|
||||
### installation and packaging
|
||||
set(NCURSES_SYSTEM_INCLUDE "include/NCurses")
|
||||
set_target_properties(NCurses PROPERTIES PUBLIC_HEADER "${NCURSES_SYSTEM_INCLUDE}/Window.hpp;${NCURSES_SYSTEM_INCLUDE}/SingleUserInput.hpp;${NCURSES_SYSTEM_INCLUDE}/PtyWindow.hpp"
|
||||
set_target_properties(NCurses PROPERTIES PUBLIC_HEADER "${NCURSES_SYSTEM_INCLUDE}/Window.hpp;${NCURSES_SYSTEM_INCLUDE}/SingleUserInput.hpp;${NCURSES_SYSTEM_INCLUDE}/PtyWindow.hpp;${NCURSES_SYSTEM_INCLUDE}/VerticalTilingWindowManager.hpp;"
|
||||
VERSION "${CMAKE_PROJECT_VERSION}")
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS NCurses ARCHIVE
|
||||
|
|
|
@ -18,8 +18,8 @@ namespace krikkel::NCurses
|
|||
using gsl::narrow;
|
||||
using std::lock_guard;
|
||||
|
||||
PtyWindow::PtyWindow(std::mutex *writeToNCursesMutex, int lines, int columns, int y, int x)
|
||||
: writeToNCursesMutex(writeToNCursesMutex), Window(lines, columns, y, x)
|
||||
PtyWindow::PtyWindow(std::mutex *ncursesMutex, int lines, int columns, int y, int x)
|
||||
: ncursesMutex(ncursesMutex), Window(lines, columns, y, x)
|
||||
{
|
||||
// to get the original terminal we need to shutdown ncurses for a moment
|
||||
/// @todo maybe try `reset_prog_mode()` and `reset_shell_mode()` instead
|
||||
|
@ -239,7 +239,7 @@ namespace krikkel::NCurses
|
|||
character = *vTermCell.chars;
|
||||
|
||||
{
|
||||
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||
lock_guard nCursesLock(*ncursesMutex);
|
||||
setcchar(&converted, &character, formatting, colorPair, NULL);
|
||||
move(cellPosition.row, cellPosition.col);
|
||||
chgat(1, formatting, colorPair, NULL);
|
||||
|
@ -249,14 +249,14 @@ namespace krikkel::NCurses
|
|||
|
||||
int PtyWindow::refresh()
|
||||
{
|
||||
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||
lock_guard nCursesLock(*ncursesMutex);
|
||||
move(cursorY, cursorX);
|
||||
return NCursesWindow::refresh();
|
||||
}
|
||||
|
||||
/// @todo potential racing condition where drawing into terminal while
|
||||
/// resizing?
|
||||
int PtyWindow::wresize(int rows, int cols)
|
||||
int PtyWindow::resize(int rows, int cols)
|
||||
{
|
||||
{
|
||||
lock_guard writeLock(writeToPseudoTerminalMutex);
|
||||
|
@ -269,8 +269,8 @@ namespace krikkel::NCurses
|
|||
vterm_set_size(pseudoTerminal, rows, cols);
|
||||
}
|
||||
{
|
||||
lock_guard nCursesLock(*writeToNCursesMutex);
|
||||
return NCursesWindow::wresize(rows, cols);
|
||||
lock_guard nCursesLock(*ncursesMutex);
|
||||
return Window::wresize(rows, cols);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
63
VerticalTilingWindowManager.cpp
Normal file
63
VerticalTilingWindowManager.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @author Christian Burger (christian@krikkel.de)
|
||||
*/
|
||||
|
||||
#include <NCurses/VerticalTilingWindowManager.hpp>
|
||||
#include <NCurses/Window.hpp>
|
||||
#include <ncursesw/ncurses.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace krikkel::NCurses
|
||||
{
|
||||
using std::list;
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
using std::find;
|
||||
|
||||
VerticalTilingWindowManager::VerticalTilingWindowManager(NCursesWindow *rootWindow, mutex *ncursesMutex)
|
||||
: rootWindow(rootWindow), ncursesMutex(ncursesMutex)
|
||||
{}
|
||||
|
||||
void VerticalTilingWindowManager::addWindow(Window *window)
|
||||
{
|
||||
stack.push_back(window);
|
||||
}
|
||||
|
||||
void VerticalTilingWindowManager::refresh()
|
||||
{
|
||||
rootWindow->refresh();
|
||||
for(Window *window : stack)
|
||||
window->refresh();
|
||||
}
|
||||
|
||||
void VerticalTilingWindowManager::updateLayout()
|
||||
{
|
||||
int availableWidth = rootWindow->width();
|
||||
int availableHeight = rootWindow->height();
|
||||
int windowHeight = availableHeight / stack.size() - 1;
|
||||
if((windowHeight + 1) * stack.size() < availableHeight)
|
||||
++windowHeight;
|
||||
|
||||
list<Window *>::iterator it = stack.begin();
|
||||
uint16_t y = 0;
|
||||
for(size_t index = 0
|
||||
; index < stack.size() - 1
|
||||
; ++index)
|
||||
{
|
||||
resizeWindowInStack(*it++, y, windowHeight, availableWidth);
|
||||
y += windowHeight;
|
||||
{
|
||||
lock_guard lock(*ncursesMutex);
|
||||
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);
|
||||
}
|
||||
}
|
13
Window.cpp
13
Window.cpp
|
@ -3,9 +3,17 @@
|
|||
*/
|
||||
|
||||
#include <NCurses/Window.hpp>
|
||||
#include <NCurses/VerticalTilingWindowManager.hpp>
|
||||
|
||||
namespace krikkel::NCurses
|
||||
{
|
||||
Window::Window(VerticalTilingWindowManager *windowManager)
|
||||
: NCursesWindow(0, 0, 0, 0)
|
||||
{
|
||||
windowManager->addWindow(this);
|
||||
windowManager->updateLayout();
|
||||
}
|
||||
|
||||
Window::Window(int lines, int columns, int y, int x)
|
||||
: NCursesWindow(lines, columns, y, x)
|
||||
{}
|
||||
|
@ -37,4 +45,9 @@ namespace krikkel::NCurses
|
|||
return SingleUserInput(result, input);
|
||||
}
|
||||
|
||||
int Window::resize(int rows, int cols)
|
||||
{
|
||||
return NCursesWindow::wresize(rows, cols);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* @brief `ncurses` window displaying contents of a pseudo terminal
|
||||
* @author Christian Burger (christian@krikkel.de)
|
||||
* @todo remove all invalid constructors
|
||||
*/
|
||||
|
||||
#ifndef __WINDOW_H__
|
||||
#define __WINDOW_H__
|
||||
|
||||
#include "SingleUserInput.hpp"
|
||||
#include "Window.hpp"
|
||||
|
||||
#include <cursesw.h>
|
||||
|
@ -21,7 +21,7 @@ namespace krikkel::NCurses
|
|||
class PtyWindow : public Window
|
||||
{
|
||||
public:
|
||||
PtyWindow(std::mutex *writeToNCursesMutex, int lines, int columns, int y, int x);
|
||||
PtyWindow(std::mutex *ncursesMutex, int lines, int columns, int y, int x);
|
||||
~PtyWindow();
|
||||
|
||||
int getFdPtyClient() const;
|
||||
|
@ -30,14 +30,14 @@ namespace krikkel::NCurses
|
|||
void writeKeyToClient(VTermKey key);
|
||||
|
||||
int refresh() override;
|
||||
int wresize(int rows, int cols);
|
||||
virtual int resize(int rows, int cols) override;
|
||||
|
||||
private:
|
||||
int fdPtyHost, fdPtyClient;
|
||||
struct termios terminalParameters;
|
||||
VTerm *pseudoTerminal;
|
||||
std::mutex writeToPseudoTerminalMutex;
|
||||
std::mutex *writeToNCursesMutex;
|
||||
std::mutex *ncursesMutex;
|
||||
VTermScreen *pseudoTerminalScreen;
|
||||
static VTermScreenCallbacks screenCallbacks;
|
||||
/// @todo one line is at most 4096 chars long
|
||||
|
|
35
include/NCurses/VerticalTilingWindowManager.hpp
Normal file
35
include/NCurses/VerticalTilingWindowManager.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* @brief Window manager
|
||||
* @author Christian Burger (christian@krikkel.de)
|
||||
*/
|
||||
|
||||
#ifndef C10F5DF3_1DB4_4714_A84D_115F492F5CDC
|
||||
#define C10F5DF3_1DB4_4714_A84D_115F492F5CDC
|
||||
|
||||
#include <ncursesw/cursesw.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
|
||||
namespace krikkel::NCurses
|
||||
{
|
||||
class Window;
|
||||
|
||||
class VerticalTilingWindowManager
|
||||
{
|
||||
public:
|
||||
VerticalTilingWindowManager(NCursesWindow *rootWindow, std::mutex *ncursesMutex);
|
||||
void addWindow(Window *window);
|
||||
void refresh();
|
||||
void updateLayout();
|
||||
|
||||
private:
|
||||
NCursesWindow *rootWindow;
|
||||
std::mutex *ncursesMutex;
|
||||
std::list<Window *> stack;
|
||||
|
||||
void resizeWindowInStack(Window *window, uint16_t y, uint16_t height, uint16_t width);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* C10F5DF3_1DB4_4714_A84D_115F492F5CDC */
|
|
@ -36,9 +36,12 @@ inline int UNDEF(get_wch)(wint_t *character) { get_wch(character); }
|
|||
|
||||
namespace krikkel::NCurses
|
||||
{
|
||||
class VerticalTilingWindowManager;
|
||||
|
||||
class Window : public NCursesWindow
|
||||
{
|
||||
public:
|
||||
Window(VerticalTilingWindowManager *windowManager);
|
||||
Window(int lines, int columns, int y, int x);
|
||||
int addnwstr(const wchar_t *wstr, int n);
|
||||
int add_wch(const cchar_t *character);
|
||||
|
@ -46,6 +49,7 @@ namespace krikkel::NCurses
|
|||
int get_wch(wint_t *character);
|
||||
|
||||
SingleUserInput readSingleUserInput();
|
||||
virtual int resize(int rows, int cols);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue