Files
Renderive/YSGraphic_Core/component/global.h
T
2026-06-16 13:33:27 +08:00

243 lines
6.3 KiB
C++

#pragma once
#include <QEvent>
#include <QGraphicsDropShadowEffect>
#include <QMap>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>
#include <QVector>
#include <QWidget>
#include <optional>
#include <QLineEdit>
#include <QPainter>
#include <QApplication>
#include <QProxyStyle>
#include <QMainWindow>
#include <QDebug>
#include <QStyledItemDelegate>
enum class Layout_Item_Type {
Fixed,
Expand
};
enum class Layout_Item_Type2 {
Fixed,
Expand
};
// 用于线性布局的元素
struct Layout_Info {
Layout_Info() = default;
Layout_Item_Type main_type{};
Layout_Item_Type2 second_type{};
Layout_Info(int key, Layout_Item_Type main_type, Layout_Item_Type2 second_type, int main_value, int second_value) :
main_type(main_type),
second_type(second_type)
{
this->key = key;
if (main_type == Layout_Item_Type::Fixed) {
len =main_value;
} else {
weight = main_value;
}
second_len = second_value;
}
int len{}; // 线性布局主要位置
int second_len{}; // 线性布局次要位置
int weight{}; // 主要位置权重布局
bool hide = false;
int key{};
};
struct Layout {
int prefix = 8, suffix = 8;
int space = 8;
int second_prefix = 8, second_suffix = 8;
QVector<Layout_Info> infos;
enum Type {
Prefix_Space,
Surfix_Space,
Center_Space
};
void set_margin(int margin){
prefix = margin;
suffix = margin;
second_prefix = margin;
second_suffix = margin;
}
Type main_type = Prefix_Space;
Type second_type = Prefix_Space;
typedef QFlags<Type> Alignment;
struct Pos {
int start;
int len;
int second_start;
int second_len;
QRect h_rect() {
return {start, second_start, len, second_len};
}
QRect v_rect() {
return {second_start, start, second_len, len};
}
};
QMap<int, Pos> cache;
std::optional<Pos> get(int key) {
auto iter = cache.find(key);
if (iter == cache.end()) {
return std::nullopt;
}
return *iter;
}
void cacl(int len, int second_len) {
QVector<Pos> ret(infos.size());
int total_fixed_pixel_size = 0;
int total_weight = 0;
int show_size = 0;
int n = infos.size();
for (int i = 0; i < n; ++i) {
auto& info = infos[i];
if (info.hide) {
continue;
}
if (info.main_type == Layout_Item_Type::Fixed) {
total_fixed_pixel_size += info.len;
}
if (info.main_type == Layout_Item_Type::Expand) {
total_weight += info.weight;
}
show_size++;
}
int show_width = total_fixed_pixel_size + (show_size - 1) * space;
int remain = len - show_width - (prefix + suffix);
int main_cur_pos = 0;
if (main_type == Type::Prefix_Space) {
main_cur_pos = prefix;
}
if (main_type == Type::Center_Space) {
main_cur_pos = (len - show_width)/2;
}
if (main_type == Type::Surfix_Space) {
main_cur_pos = len - show_width - suffix;
}
for (int i = 0; i < n; ++i) {
auto& info = infos[i];
if (info.hide) continue;
auto& pos = ret[i];
int cur_len = info.main_type == Layout_Item_Type::Fixed ? info.len :
static_cast<int>((double)remain * (double)info.weight/(double)total_weight);
pos.start = main_cur_pos;
pos.len = cur_len;
int info_second_len{};
if (info.second_type == Layout_Item_Type2::Fixed) {
info_second_len = info.second_len;
}
if (info.second_type == Layout_Item_Type2::Expand) {
info_second_len = second_len - second_prefix - second_suffix;
}
if (second_type == Type::Prefix_Space)
{
pos.second_len = second_prefix;
}
if (second_type == Type::Center_Space)
{
pos.second_start = (second_len - info_second_len) /2;
}
if (second_type == Type::Surfix_Space)
{
pos.second_start = second_len - info_second_len- second_suffix;
}
pos.second_len = info_second_len;
main_cur_pos += space + cur_len;
}
cache.clear();
for (int i = 0; i < n; ++i)
{
auto key = infos[i].key;
cache[key] = ret[i];
}
}
};
enum class Event_Type {
refresh,
Nothing
};
struct PaintAble {
PaintAble() = default;
virtual QSize sizeHint() const {
return {24, 24};
}
virtual ~PaintAble() = default;
virtual void paint(QPainter* painter, QRect rect) = 0;
// 鼠标操作
virtual Event_Type mouse_event(QEvent::Type t, QMouseEvent* e) {
return Event_Type::Nothing;
}
virtual Event_Type resize_event(QResizeEvent* e) {
return Event_Type::Nothing;
}
virtual Event_Type event(QEvent::Type t, QEvent* e) {
if (t == QEvent::Resize) {
return resize_event(dynamic_cast<QResizeEvent*>(e));
}
if (
t == QEvent::MouseButtonPress ||
t == QEvent::MouseButtonRelease ||
t == QEvent::MouseMove ||
t == QEvent::MouseButtonDblClick
) {
return mouse_event(t, dynamic_cast<QMouseEvent*>(e));
}
return Event_Type::Nothing;
}
bool show = true;
};
struct Base : QWidget {
QVector<PaintAble*> paintAbles;
void paintEvent(QPaintEvent* event) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QRect rect = event->rect();
for (auto paintAble : paintAbles) {
if (paintAble->show) {
paintAble->paint(&painter, rect);
}
}
painter.end();
}
bool event(QEvent* e) override {
auto t = e->type();
for(PaintAble* paintAble : paintAbles){
Event_Type r = paintAble->event(t, e);
if (r == Event_Type::refresh) {
update();
}
}
return QWidget::event(e);
}
};