mirror of
https://github.com/MeowLynxSea/ceditor.git
synced 2025-07-09 10:54:37 +00:00
add TextLine
This commit is contained in:
parent
0d3a8ddf74
commit
ca4d37ce3b
30
components/BaseComponent.h
Normal file
30
components/BaseComponent.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef BASE_COMPONENT_H
|
||||||
|
#define BASE_COMPONENT_H
|
||||||
|
|
||||||
|
class BaseComponent {
|
||||||
|
protected:
|
||||||
|
int top, left, width, height;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BaseComponent(int top, int left, int width, int height) : top(top), left(left), width(width), height(height) {};
|
||||||
|
virtual ~BaseComponent() {};
|
||||||
|
|
||||||
|
void setTop(int top);
|
||||||
|
void setLeft(int left);
|
||||||
|
void setWidth(int width);
|
||||||
|
void setHeight(int height);
|
||||||
|
|
||||||
|
int getTop();
|
||||||
|
int getLeft();
|
||||||
|
int getWidth();
|
||||||
|
int getHeight();
|
||||||
|
|
||||||
|
void setPosition(int top, int left);
|
||||||
|
void setSize(int width, int height);
|
||||||
|
void setBounds(int top, int left, int width, int height);
|
||||||
|
|
||||||
|
virtual void draw() = 0;
|
||||||
|
virtual void onKeyPress(int key) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BASE_COMPONENT_H
|
132
components/TextArea.h
Normal file
132
components/TextArea.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#ifndef TEXTLINE_H
|
||||||
|
#define TEXTLINE_H
|
||||||
|
|
||||||
|
#include "BaseComponent.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "../utils/RichText.h"
|
||||||
|
|
||||||
|
class TextArea : public BaseComponent {
|
||||||
|
private:
|
||||||
|
RichText text;
|
||||||
|
int viewLeft = 0, viewTop = 0; // 视图左上角坐标
|
||||||
|
|
||||||
|
int findnth(std::string str, std::string target, int n){
|
||||||
|
if(n == 0) return -1;
|
||||||
|
int count = 0;
|
||||||
|
unsigned int begin=0;
|
||||||
|
while((begin = str.find(target, begin)) != std::string::npos){
|
||||||
|
count++;
|
||||||
|
begin += target.length();
|
||||||
|
if(n == count){
|
||||||
|
return begin - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
TextArea(int top, int left, int width, int height) : BaseComponent(top, left, width, height){
|
||||||
|
text = RichText();
|
||||||
|
}
|
||||||
|
TextArea(int top, int left, int width, int height, const RichText& text) : BaseComponent(top, left, width, height){
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
~TextArea() override {}
|
||||||
|
|
||||||
|
void setText(const RichText& text) {
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
RichText getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() override {
|
||||||
|
//使用渲染边框,超出屏幕边缘的区域不渲染
|
||||||
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
//获得缓冲区信息
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||||
|
//绘制边框到缓冲区
|
||||||
|
for(int i = 0; i < height && top + i < csbi.dwSize.Y; i++) {
|
||||||
|
if(left >= 0) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left - 1), static_cast<short>(top + i - 1)});
|
||||||
|
printf("|");
|
||||||
|
}
|
||||||
|
if(left + width - 1 < csbi.dwSize.X) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + width - 2), static_cast<short>(top + i - 1)});
|
||||||
|
printf("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < width && left + i < csbi.dwSize.X; i++) {
|
||||||
|
if(top >= 0) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top - 1)});
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
if(top + height - 1 < csbi.dwSize.Y) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top + height - 2)});
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//绘制文本到缓冲区,保证不超出边框
|
||||||
|
// int textWidth = 0, i = 0;
|
||||||
|
// while(textWidth <= width - 2 && left + textWidth + 2 < csbi.dwSize.X && i < text.size()) {
|
||||||
|
// auto part = text.getParts()[i];
|
||||||
|
// SetConsoleCursorPosition(hConsole, {static_cast<short>(left + textWidth), static_cast<short>(top)});
|
||||||
|
// SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(getBackColor(part.color)) | FrontColorToWinColor(getFrontColor(part.color)));
|
||||||
|
// if(left + textWidth + part.text.length() + 2 < csbi.dwSize.X && textWidth + part.text.length() <= width - 2) {
|
||||||
|
// printf("%s", part.text.c_str());
|
||||||
|
// } else {
|
||||||
|
// printf("%s", part.text.substr(0, std::min(csbi.dwSize.X - left - textWidth - 2, width - 2 - textWidth)).c_str());
|
||||||
|
// }
|
||||||
|
// textWidth += text.getParts()[i].text.length();
|
||||||
|
// i++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 根据换行预处理文本
|
||||||
|
std::vector<RichText> lines;
|
||||||
|
RichText line;
|
||||||
|
for(auto part : text.getParts()) {
|
||||||
|
if(part.text.find('\n') == std::string::npos) {
|
||||||
|
line += part;
|
||||||
|
} else {
|
||||||
|
unsigned int begin = 0;
|
||||||
|
while((begin = part.text.find('\n', begin)) != std::string::npos) {
|
||||||
|
line += StringPart(part.text.substr(0, begin), part.color);
|
||||||
|
lines.push_back(line);
|
||||||
|
line = RichText();
|
||||||
|
part.text = part.text.substr(begin + 1);
|
||||||
|
}
|
||||||
|
line += part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = viewTop; i < viewTop + height - 2 && i < lines.size(); i++) {
|
||||||
|
line = lines[i];
|
||||||
|
RichText drawTarget = line.substr(viewLeft, width - 2);
|
||||||
|
int textWidth = 0, ite = 0;
|
||||||
|
while(textWidth <= width - 2 && left + textWidth + 2 < csbi.dwSize.X && ite < text.size()) {
|
||||||
|
auto part = line.getParts()[i];
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + textWidth), static_cast<short>(top)});
|
||||||
|
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(getBackColor(part.color)) | FrontColorToWinColor(getFrontColor(part.color)));
|
||||||
|
if(left + textWidth + part.text.length() + 2 < csbi.dwSize.X && textWidth + part.text.length() <= width - 2) {
|
||||||
|
printf("%s", part.text.c_str());
|
||||||
|
} else {
|
||||||
|
printf("%s", part.text.substr(0, std::min(csbi.dwSize.X - left - textWidth - 2, width - 2 - textWidth)).c_str());
|
||||||
|
}
|
||||||
|
textWidth += part.text.length();
|
||||||
|
ite++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onKeyPress(int key) override {
|
||||||
|
//不处理按键
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
23
components/TextArea_test.cpp
Normal file
23
components/TextArea_test.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "BaseComponent.h"
|
||||||
|
#include "TextArea.h"
|
||||||
|
#include "../utils/RichText.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RichText richText;
|
||||||
|
richText = "Hello, World";
|
||||||
|
richText += StringPart(" with colors!", COLOR_RED);
|
||||||
|
richText += " And more text.";
|
||||||
|
richText += StringPart(" And more more more text.", COLOR_GREEN);
|
||||||
|
richText += " And more more more more more text.";
|
||||||
|
richText += StringPart(" And more more more more more more text.", COLOR_BLUE);
|
||||||
|
richText += " And more more more more more more more text.";
|
||||||
|
richText += StringPart(" And more more more more more more more more text.", COLOR_YELLOW);
|
||||||
|
richText += " And more more more more more more more more more text.";
|
||||||
|
richText += StringPart(" And more more more more more more more more more more text.", COLOR_CYAN);
|
||||||
|
|
||||||
|
TextArea textArea(3, 3, 40, 5, richText);
|
||||||
|
textArea.draw();
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
80
components/TextLine.h
Normal file
80
components/TextLine.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef TEXTLINE_H
|
||||||
|
#define TEXTLINE_H
|
||||||
|
|
||||||
|
#include "BaseComponent.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include "../utils/RichText.h"
|
||||||
|
|
||||||
|
class TextLine : public BaseComponent {
|
||||||
|
private:
|
||||||
|
RichText text;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TextLine(int top, int left, int width, int height) : BaseComponent(top, left, width, height){
|
||||||
|
text = RichText();
|
||||||
|
|
||||||
|
}
|
||||||
|
TextLine(int top, int left, int width, int height, const RichText& text) : BaseComponent(top, left, width, height){
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
~TextLine() override {}
|
||||||
|
|
||||||
|
void setText(const RichText& text) {
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
RichText getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() override {
|
||||||
|
//使用渲染边框,超出屏幕边缘的区域不渲染
|
||||||
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
//获得缓冲区信息
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||||
|
//绘制边框到缓冲区
|
||||||
|
for(int i = 0; i < height && top + i < csbi.dwSize.Y; i++) {
|
||||||
|
if(left >= 0) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left - 1), static_cast<short>(top + i - 1)});
|
||||||
|
printf("|");
|
||||||
|
}
|
||||||
|
if(left + width - 1 < csbi.dwSize.X) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + width - 2), static_cast<short>(top + i - 1)});
|
||||||
|
printf("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < width && left + i < csbi.dwSize.X; i++) {
|
||||||
|
if(top >= 0) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top - 1)});
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
if(top + height - 1 < csbi.dwSize.Y) {
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top + height - 2)});
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//绘制文本到缓冲区,保证不超出边框
|
||||||
|
int textWidth = 0, i = 0;
|
||||||
|
while(textWidth <= width - 2 && left + textWidth + 2 < csbi.dwSize.X && i < text.size()) {
|
||||||
|
auto part = text.getParts()[i];
|
||||||
|
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + textWidth), static_cast<short>(top)});
|
||||||
|
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(getBackColor(part.color)) | FrontColorToWinColor(getFrontColor(part.color)));
|
||||||
|
if(left + textWidth + part.text.length() + 2 < csbi.dwSize.X && textWidth + part.text.length() <= width - 2) {
|
||||||
|
printf("%s", part.text.c_str());
|
||||||
|
} else {
|
||||||
|
printf("%s", part.text.substr(0, std::min(csbi.dwSize.X - left - textWidth - 2, width - 2 - textWidth)).c_str());
|
||||||
|
}
|
||||||
|
textWidth += part.text.length();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onKeyPress(int key) override {
|
||||||
|
//不处理按键
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
20
components/TextLine_test.cpp
Normal file
20
components/TextLine_test.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "BaseComponent.h"
|
||||||
|
#include "TextLine.h"
|
||||||
|
#include "../utils/RichText.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RichText richText;
|
||||||
|
richText = "Hello, World";
|
||||||
|
richText += StringPart(" with colors!", COLOR_RED);
|
||||||
|
|
||||||
|
TextLine textLine(2, 5, 23, 3);
|
||||||
|
textLine.setText(richText);
|
||||||
|
textLine.draw();
|
||||||
|
|
||||||
|
TextLine textLine2(6, 5, 50, 3);
|
||||||
|
textLine2.setText(richText + StringPart(" and more colors!", COLOR_LIGHTCYAN));
|
||||||
|
textLine2.draw();
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
20
main.cpp
20
main.cpp
@ -0,0 +1,20 @@
|
|||||||
|
#include "components/BaseComponent.h"
|
||||||
|
#include "components/TextLine.h"
|
||||||
|
#include "utils/RichText.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RichText richText;
|
||||||
|
richText = "Hello, World";
|
||||||
|
richText += StringPart(" with colors!", COLOR_RED);
|
||||||
|
|
||||||
|
TextLine textLine(2, 2, 23, 3);
|
||||||
|
textLine.setText(richText);
|
||||||
|
textLine.draw();
|
||||||
|
|
||||||
|
TextLine textLine2(7, 5, 40, 3);
|
||||||
|
textLine2.setText(richText + StringPart(" and more colors!", COLOR_LIGHTCYAN));
|
||||||
|
textLine2.draw();
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
@ -143,6 +143,18 @@ public:
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int size() const {
|
||||||
|
return parts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length() const {
|
||||||
|
int result = 0;
|
||||||
|
for (const auto& part : parts) {
|
||||||
|
result += part.text.length();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user