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