boxes
parent
7aae8272c3
commit
caaf91e9c7
|
@ -12,6 +12,9 @@
|
|||
#include <vector>
|
||||
#include <blt/math/math.h>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
#include "memory.h"
|
||||
#include <variant>
|
||||
|
||||
namespace blt::string
|
||||
{
|
||||
|
@ -308,31 +311,187 @@ namespace blt::string
|
|||
std::vector<std::string> createTable(bool top = false, bool bottom = false);
|
||||
};
|
||||
|
||||
struct tree_node {
|
||||
std::string data;
|
||||
std::string title;
|
||||
std::vector<tree_node*> children;
|
||||
static inline constexpr size_t MAX_CHILDREN = 16;
|
||||
|
||||
struct box_format
|
||||
{
|
||||
size_t boxHPadding = 4;
|
||||
size_t boxVPadding = 2;
|
||||
};
|
||||
|
||||
class BinaryTreeFormatter
|
||||
struct tree_format
|
||||
{
|
||||
public:
|
||||
// data classes
|
||||
struct TreeFormat
|
||||
{
|
||||
int verticalSpacing;
|
||||
int horizontalSpacing;
|
||||
box_format boxFormat;
|
||||
|
||||
int verticalPadding;
|
||||
int horizontalPadding;
|
||||
|
||||
// should we remove preceding spaces?
|
||||
bool collapse = false;
|
||||
bool collapse = true;
|
||||
|
||||
TreeFormat(): verticalSpacing(2), horizontalSpacing(4), verticalPadding(1), horizontalPadding(4)
|
||||
tree_format(): boxFormat{}, verticalPadding(1), horizontalPadding(4)
|
||||
{}
|
||||
};
|
||||
|
||||
struct tree_node
|
||||
{
|
||||
std::string data;
|
||||
std::string title;
|
||||
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
|
||||
{
|
||||
public:
|
||||
// data classes
|
||||
|
||||
|
||||
struct Node
|
||||
{
|
||||
std::string data;
|
||||
|
@ -357,11 +516,12 @@ namespace blt::string
|
|||
};
|
||||
|
||||
private:
|
||||
TreeFormat format;
|
||||
tree_format format;
|
||||
|
||||
Node* root = nullptr;
|
||||
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;
|
||||
|
|
|
@ -32,9 +32,9 @@ class window {
|
|||
KEY_MAP mouseDown{};
|
||||
public:
|
||||
window() = default;
|
||||
window(int width, int height) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
window(int width_, int height_) {
|
||||
m_width = width_;
|
||||
m_height = height_;
|
||||
}
|
||||
virtual void createWindow() = 0;
|
||||
virtual void startMainLoop() = 0;
|
||||
|
@ -42,7 +42,7 @@ class window {
|
|||
virtual ~window() = 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 getHeight() const {return m_height;};
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ std::vector<std::string> blt::string::BinaryTreeFormatter::construct()
|
|||
size_t lastLineLength = 0;
|
||||
const size_t lineHeight = format.verticalPadding * 2 + 3;
|
||||
//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())
|
||||
{
|
||||
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!");
|
||||
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] += box[i];
|
||||
}
|
||||
|
@ -414,3 +414,9 @@ std::string blt::string::createPadding(size_t length, char spacing)
|
|||
padding += spacing;
|
||||
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;
|
||||
format.horizontalPadding = 3;
|
||||
format.verticalPadding = 0;
|
||||
format.horizontalSpacing = 3;
|
||||
format.boxVPadding = 3;
|
||||
format.collapse = true;
|
||||
blt::string::BinaryTreeFormatter treeFormatter("I love Men", format);
|
||||
treeFormatter.getRoot()->with(
|
||||
|
|
Loading…
Reference in New Issue