200 lines
6.9 KiB
C++
200 lines
6.9 KiB
C++
#include "Tree_View.h"
|
|
#include <QDebug>
|
|
#include <QMouseEvent>
|
|
#include <QPainter>
|
|
#include <queue>
|
|
#include <stack>
|
|
#include "../../component/SVG.h"
|
|
#include "Tree_Model.h"
|
|
namespace Psc {
|
|
Tree_View* create_Tree_View() {
|
|
auto cn = [](const QString& text) {
|
|
auto ret = new Node();
|
|
ret->text = text;
|
|
return ret;
|
|
};
|
|
auto ret = new Tree_View();
|
|
auto& roots = ret->model->roots;
|
|
int a1 = 10;
|
|
int a2 = 4;
|
|
int a3 = 10;
|
|
for (int i1 = 0; i1 < a1; i1++) {
|
|
QString t1 = QString("%1").arg(i1);
|
|
auto n1 = cn(t1);
|
|
for (int i2 = 0; i2 < a2; i2++) {
|
|
QString t2 = t1 + QString("_%1").arg(i2);
|
|
auto n2 = cn(t2);
|
|
for (int i3 = 0; i3 < a3; i3++) {
|
|
QString t3 = t2 + QString("_%1").arg(i3);
|
|
auto n3 = cn(t3);
|
|
n2->add_child(n3);
|
|
}
|
|
n1->add_child(n2);
|
|
}
|
|
roots.push_back(n1);
|
|
}
|
|
return ret;
|
|
}
|
|
QPoint Tree_View::to_inside_pos(QPoint widget_pos) {
|
|
auto rect = get_view_rect();
|
|
return widget_pos + this->_view_pos - QPoint(rect.left(), rect.top());
|
|
}
|
|
QPoint Tree_View::to_widget_pos(QPoint inside_pos) {
|
|
auto rect = get_view_rect();
|
|
return inside_pos - this->_view_pos + QPoint(rect.left(), rect.top());
|
|
}
|
|
QRect Tree_View::get_view_rect() {
|
|
int w = width() - left_margin - right_margin;
|
|
int h = height() - top_margin - bottom_margin;
|
|
return QRect(left_margin, top_margin, w, h);
|
|
}
|
|
Tree_View::Tree_View() {
|
|
_view_pos = {0, 0};
|
|
//_view_pos = {0, 0};
|
|
model = new Tree_Model();
|
|
}
|
|
void Tree_View::paintEvent(QPaintEvent* event) {
|
|
QPainter painter(this);
|
|
QRect view_rect = get_view_rect();
|
|
painter.drawRect(view_rect);
|
|
// painter.fillRect(rect(), Qt::yellow);
|
|
auto& roots = model->roots;
|
|
QFontMetrics fm(font);
|
|
static auto expand = SVG_Image_Render().set_path(":/you_jian_tou.svg").create().to_image({model->png_len, model->png_len}, Qt::black);
|
|
static auto retract = expand.transformed(QTransform().rotate(90));
|
|
painter.setClipRect(view_rect);
|
|
select_node(roots, _view_pos.y(), view_rect.height(), model->space, [&](Node* cur, int depth, int cur_inside_y) {
|
|
int x = depth * model->tab_width;
|
|
int cur_h = cur->height;
|
|
{
|
|
// 绘制箭头
|
|
QPoint sta = {x, cur_inside_y};
|
|
QPoint end = {x + model->png_len, cur_inside_y + model->png_len};
|
|
QPoint wsta = to_widget_pos(sta);
|
|
QPoint wend = to_widget_pos(end);
|
|
QRect r(wsta, wend);
|
|
painter.drawRect(r);
|
|
painter.drawImage(r.topLeft(), cur->expand ? expand : retract);
|
|
}
|
|
{
|
|
// 绘制文字
|
|
x += model->png_len;
|
|
QPoint sta = {x, cur_inside_y + cur_h};
|
|
painter.drawText(to_widget_pos(sta), cur->text);
|
|
}
|
|
});
|
|
h_bar.draw(&painter);
|
|
v_bar.draw(&painter);
|
|
QWidget::paintEvent(event);
|
|
}
|
|
void Tree_View::mouse_event(QMouseEvent* event, QEvent::Type type) {
|
|
QRect view_rect = get_view_rect();
|
|
QPoint pos = event->pos();
|
|
bool on_h_slider = h_bar.get_slider_rect(width(), height()).contains(event->pos());
|
|
bool on_v_slider = v_bar.get_slider_rect(width(), height()).contains(event->pos());
|
|
if (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick) {
|
|
select_node(model->roots, _view_pos.y(), view_rect.height(), model->space, [&](Node* cur, int depth, int cur_inside_y) {
|
|
int x = depth * model->tab_width;
|
|
int cur_h = cur->height;
|
|
QPoint sta = {x, cur_inside_y};
|
|
QPoint end = {x + model->png_len, cur_inside_y + model->png_len};
|
|
QPoint wsta = to_widget_pos(sta);
|
|
QPoint wend = to_widget_pos(end);
|
|
QRect r(wsta, wend);
|
|
if (r.contains(pos)) {
|
|
cur->expand = !cur->expand;
|
|
qDebug() << "1111111 1 " << cur->expand;
|
|
update();
|
|
}
|
|
});
|
|
}
|
|
if (type == QEvent::MouseButtonPress) {
|
|
if (on_h_slider) {
|
|
is_dragging = true;
|
|
drag_type = H_scrollBar;
|
|
setCursor(Qt::SizeHorCursor);
|
|
}
|
|
else if (on_v_slider) {
|
|
is_dragging = true;
|
|
drag_type = V_scrollBar;
|
|
setCursor(Qt::SizeVerCursor);
|
|
}
|
|
else {
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
if (is_dragging) {
|
|
start_pos = event->pos();
|
|
save_pos = _view_pos;
|
|
}
|
|
}
|
|
else if (type == QEvent::MouseButtonRelease) {
|
|
if (on_h_slider) {
|
|
setCursor(Qt::SizeHorCursor);
|
|
}
|
|
else if (on_v_slider) {
|
|
setCursor(Qt::SizeVerCursor);
|
|
}
|
|
else {
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
}
|
|
else if (type == QEvent::MouseMove) {
|
|
if (on_h_slider) {
|
|
setCursor(Qt::SizeHorCursor);
|
|
}
|
|
else if (on_v_slider) {
|
|
setCursor(Qt::SizeVerCursor);
|
|
}
|
|
else {
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
if (!is_dragging)
|
|
return;
|
|
QPoint cur_pos = event->pos();
|
|
int delta_x = cur_pos.x() - start_pos.x(); // 计算X轴的拖动距离
|
|
int delta_y = cur_pos.y() - start_pos.y(); // 计算Y轴的拖动距离
|
|
if (drag_type == H_scrollBar) {
|
|
int end_x = save_pos.x() + delta_x / h_bar.rate();
|
|
_view_pos.setX(end_x);
|
|
h_bar.set_view_pos(end_x);
|
|
}
|
|
else if (drag_type == V_scrollBar) {
|
|
int end_y = save_pos.y() + delta_y / v_bar.rate();
|
|
_view_pos.setY(end_y);
|
|
v_bar.set_view_pos(end_y);
|
|
}
|
|
else {
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
update();
|
|
}
|
|
}
|
|
bool Tree_View::event(QEvent* e) {
|
|
if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseMove ||
|
|
e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseButtonDblClick) {
|
|
auto event = static_cast<QMouseEvent*>(e);
|
|
mouse_event(event, event->type());
|
|
return true;
|
|
}
|
|
return QWidget::event(e);
|
|
}
|
|
void Tree_View::resizeEvent(QResizeEvent* event) {
|
|
QRect cells_view_rect = get_view_rect();
|
|
h_bar.start = cells_view_rect.x();
|
|
h_bar.resize(cells_view_rect.width(), cells_view_rect.width(), model->width());
|
|
v_bar.start = cells_view_rect.y();
|
|
v_bar.resize(cells_view_rect.height(), cells_view_rect.height(), model->height());
|
|
QWidget::resizeEvent(event);
|
|
}
|
|
void Tree_View::wheelEvent(QWheelEvent* event) {
|
|
double single_step = 12;
|
|
double v_steps = event->angleDelta().y() / 120.0;
|
|
v_bar.set_view_pos(v_bar.get_view_pos() - v_steps * single_step);
|
|
double h_steps = event->angleDelta().x() / 120.0;
|
|
h_bar.set_view_pos(h_bar.get_view_pos() - h_steps * single_step);
|
|
_view_pos.setX(h_bar.view_pos());
|
|
_view_pos.setY(v_bar.view_pos());
|
|
update();
|
|
}
|
|
} // namespace Psc
|