boxes
parent
7aae8272c3
commit
caaf91e9c7
|
@ -12,6 +12,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <blt/math/math.h>
|
#include <blt/math/math.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string_view>
|
||||||
|
#include "memory.h"
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace blt::string
|
namespace blt::string
|
||||||
{
|
{
|
||||||
|
@ -308,30 +311,186 @@ namespace blt::string
|
||||||
std::vector<std::string> createTable(bool top = false, bool bottom = false);
|
std::vector<std::string> createTable(bool top = false, bool bottom = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tree_node {
|
static inline constexpr size_t MAX_CHILDREN = 16;
|
||||||
|
|
||||||
|
struct box_format
|
||||||
|
{
|
||||||
|
size_t boxHPadding = 4;
|
||||||
|
size_t boxVPadding = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tree_format
|
||||||
|
{
|
||||||
|
box_format boxFormat;
|
||||||
|
|
||||||
|
int verticalPadding;
|
||||||
|
int horizontalPadding;
|
||||||
|
|
||||||
|
// should we remove preceding spaces?
|
||||||
|
bool collapse = true;
|
||||||
|
|
||||||
|
tree_format(): boxFormat{}, verticalPadding(1), horizontalPadding(4)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tree_node
|
||||||
|
{
|
||||||
std::string data;
|
std::string data;
|
||||||
std::string title;
|
std::string title;
|
||||||
std::vector<tree_node*> children;
|
tree_node* parent;
|
||||||
|
blt::static_vector<tree_node*, 16> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ascii_data
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
char* data_;
|
||||||
|
size_t width_ = 0;
|
||||||
|
size_t height_ = 0;
|
||||||
|
size_t size_ = 0;
|
||||||
|
public:
|
||||||
|
ascii_data(size_t width, size_t height): data_(new char[width * height]), width_(width), height_(height), size_(width * height)
|
||||||
|
{
|
||||||
|
// he he he
|
||||||
|
memset(data_, ' ', width * height);
|
||||||
|
}
|
||||||
|
|
||||||
|
ascii_data(const ascii_data& copy) = delete;
|
||||||
|
|
||||||
|
ascii_data(ascii_data&& move) noexcept
|
||||||
|
{
|
||||||
|
data_ = move.data_;
|
||||||
|
width_ = move.width_;
|
||||||
|
height_ = move.height_;
|
||||||
|
size_ = move.size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ascii_data& operator=(const ascii_data& copy) = delete;
|
||||||
|
|
||||||
|
ascii_data& operator=(ascii_data&& move) noexcept
|
||||||
|
{
|
||||||
|
delete[] data_;
|
||||||
|
data_ = move.data_;
|
||||||
|
width_ = move.width_;
|
||||||
|
height_ = move.height_;
|
||||||
|
size_ = move.size_;
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
char at(size_t x, size_t y)
|
||||||
|
{
|
||||||
|
return data_[x * width_ + y];
|
||||||
|
}
|
||||||
|
|
||||||
|
char* data()
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> toVec()
|
||||||
|
{
|
||||||
|
std::vector<std::string> vec;
|
||||||
|
for (size_t j = 0; j < height(); j++)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
line.reserve(width());
|
||||||
|
for (int i = 0; i < width(); i++)
|
||||||
|
{
|
||||||
|
line += at(i, j);
|
||||||
|
}
|
||||||
|
vec.push_back(std::move(line));
|
||||||
|
}
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] char* data() const
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t height() const
|
||||||
|
{
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ascii_data()
|
||||||
|
{
|
||||||
|
delete[] data_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ascii_box
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string_view title;
|
||||||
|
std::string_view data;
|
||||||
|
size_t width_;
|
||||||
|
size_t height_;
|
||||||
|
public:
|
||||||
|
ascii_box(std::string_view title, std::string_view data, const box_format& format): title(title), data(data)
|
||||||
|
{
|
||||||
|
width_ = std::max(data.length(), title.length()) + (format.boxHPadding * 2);
|
||||||
|
height_ = 5 + (format.boxVPadding * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t width() const
|
||||||
|
{
|
||||||
|
return width_ + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t height() const
|
||||||
|
{
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t raw_width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ascii_boxes
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<ascii_box> boxes_;
|
||||||
|
size_t width = 1;
|
||||||
|
size_t height = 0;
|
||||||
|
public:
|
||||||
|
ascii_boxes() = default;
|
||||||
|
|
||||||
|
inline void push_back(ascii_box&& box)
|
||||||
|
{
|
||||||
|
width += box.raw_width() + 1;
|
||||||
|
// should all be the same
|
||||||
|
height = std::max(box.height(), height);
|
||||||
|
boxes_.push_back(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<ascii_box>& boxes()
|
||||||
|
{
|
||||||
|
return boxes_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::variant<ascii_box, ascii_boxes> box_type;
|
||||||
|
|
||||||
|
ascii_data constructBox(const box_type& box);
|
||||||
|
|
||||||
class BinaryTreeFormatter
|
class BinaryTreeFormatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// data classes
|
// data classes
|
||||||
struct TreeFormat
|
|
||||||
{
|
|
||||||
int verticalSpacing;
|
|
||||||
int horizontalSpacing;
|
|
||||||
|
|
||||||
int verticalPadding;
|
|
||||||
int horizontalPadding;
|
|
||||||
|
|
||||||
// should we remove preceding spaces?
|
|
||||||
bool collapse = false;
|
|
||||||
|
|
||||||
TreeFormat(): verticalSpacing(2), horizontalSpacing(4), verticalPadding(1), horizontalPadding(4)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
|
@ -357,11 +516,12 @@ namespace blt::string
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeFormat format;
|
tree_format format;
|
||||||
|
|
||||||
Node* root = nullptr;
|
Node* root = nullptr;
|
||||||
public:
|
public:
|
||||||
explicit BinaryTreeFormatter(std::string rootData, TreeFormat format = {}): format(std::move(format)), root(new Node(std::move(rootData)))
|
explicit BinaryTreeFormatter(std::string rootData, tree_format format = {}):
|
||||||
|
format(std::move(format)), root(new Node(std::move(rootData)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::vector<std::string> generateBox(Node* node) const;
|
std::vector<std::string> generateBox(Node* node) const;
|
||||||
|
|
|
@ -32,9 +32,9 @@ class window {
|
||||||
KEY_MAP mouseDown{};
|
KEY_MAP mouseDown{};
|
||||||
public:
|
public:
|
||||||
window() = default;
|
window() = default;
|
||||||
window(int width, int height) {
|
window(int width_, int height_) {
|
||||||
m_width = width;
|
m_width = width_;
|
||||||
m_height = height;
|
m_height = height_;
|
||||||
}
|
}
|
||||||
virtual void createWindow() = 0;
|
virtual void createWindow() = 0;
|
||||||
virtual void startMainLoop() = 0;
|
virtual void startMainLoop() = 0;
|
||||||
|
@ -42,7 +42,7 @@ class window {
|
||||||
virtual ~window() = 0;
|
virtual ~window() = 0;
|
||||||
|
|
||||||
virtual inline bool setResizeable(bool resizeEnabled) = 0;
|
virtual inline bool setResizeable(bool resizeEnabled) = 0;
|
||||||
virtual inline bool setWindowSize(int width, int height) = 0;
|
virtual inline bool setWindowSize(int width_, int height_) = 0;
|
||||||
[[nodiscard]] inline int getWidth() const {return m_width;};
|
[[nodiscard]] inline int getWidth() const {return m_width;};
|
||||||
[[nodiscard]] inline int getHeight() const {return m_height;};
|
[[nodiscard]] inline int getHeight() const {return m_height;};
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ std::vector<std::string> blt::string::BinaryTreeFormatter::construct()
|
||||||
size_t lastLineLength = 0;
|
size_t lastLineLength = 0;
|
||||||
const size_t lineHeight = format.verticalPadding * 2 + 3;
|
const size_t lineHeight = format.verticalPadding * 2 + 3;
|
||||||
//std::cout << levels.size() << "\n";
|
//std::cout << levels.size() << "\n";
|
||||||
const size_t verticalSpacing = format.verticalSpacing % 2 == 0 ? format.verticalSpacing + 1 : format.verticalSpacing;
|
const size_t verticalSpacing = format.boxHPadding % 2 == 0 ? format.boxHPadding + 1 : format.boxHPadding;
|
||||||
while (!levels.empty())
|
while (!levels.empty())
|
||||||
{
|
{
|
||||||
std::vector<std::string> currentLines;
|
std::vector<std::string> currentLines;
|
||||||
|
@ -242,7 +242,7 @@ std::vector<std::string> blt::string::BinaryTreeFormatter::construct()
|
||||||
BLT_ASSERT(currentLines.size() == box.size() && "Box lines should match current lines!");
|
BLT_ASSERT(currentLines.size() == box.size() && "Box lines should match current lines!");
|
||||||
for (size_t i = 0; i < currentLines.size(); i++)
|
for (size_t i = 0; i < currentLines.size(); i++)
|
||||||
{
|
{
|
||||||
currentLines[i] += createPadding(format.horizontalSpacing);
|
currentLines[i] += createPadding(format.boxVPadding);
|
||||||
//currentLines[i] += createPadding(format.horizontalSpacing + static_cast<std::int64_t>(lineLength / (n.level.size() + 1)));
|
//currentLines[i] += createPadding(format.horizontalSpacing + static_cast<std::int64_t>(lineLength / (n.level.size() + 1)));
|
||||||
currentLines[i] += box[i];
|
currentLines[i] += box[i];
|
||||||
}
|
}
|
||||||
|
@ -414,3 +414,9 @@ std::string blt::string::createPadding(size_t length, char spacing)
|
||||||
padding += spacing;
|
padding += spacing;
|
||||||
return padding;
|
return padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blt::string::ascii_data blt::string::constructBox(const blt::string::box_type& box)
|
||||||
|
{
|
||||||
|
|
||||||
|
return blt::string::ascii_data(0, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ void blt::test::utility::run()
|
||||||
blt::string::BinaryTreeFormatter::TreeFormat format;
|
blt::string::BinaryTreeFormatter::TreeFormat format;
|
||||||
format.horizontalPadding = 3;
|
format.horizontalPadding = 3;
|
||||||
format.verticalPadding = 0;
|
format.verticalPadding = 0;
|
||||||
format.horizontalSpacing = 3;
|
format.boxVPadding = 3;
|
||||||
format.collapse = true;
|
format.collapse = true;
|
||||||
blt::string::BinaryTreeFormatter treeFormatter("I love Men", format);
|
blt::string::BinaryTreeFormatter treeFormatter("I love Men", format);
|
||||||
treeFormatter.getRoot()->with(
|
treeFormatter.getRoot()->with(
|
||||||
|
|
Loading…
Reference in New Issue