Refactor of Panel
- Changing Visuals as subclass of Nodes - Removing Visual painting in Node Class - New Visual Class that is part of the node module - Moving ResizeBoundingBox from Visuals to Panel - Introducing a VisualContainer where the Visuals are rendered in - Adding property window - Removing Visual Container in Documents
This commit is contained in:
@@ -18,39 +18,30 @@ void Document::load(QJsonObject content)
|
||||
return;
|
||||
}
|
||||
|
||||
Visual *Document::createVisual(VisualType type)
|
||||
void Document::createVisual(VisualType type)
|
||||
{
|
||||
VisualContainer container;
|
||||
container.type = type;
|
||||
|
||||
if (type == VisualType::Test) {
|
||||
Label *label = new Label(this);
|
||||
label->setPanel(m_panel);
|
||||
label->setPanel(m_panel, QPoint(200, 200));
|
||||
label->setNodeEditor(m_nodeeditor);
|
||||
m_nodeeditor->addNode(label);
|
||||
|
||||
connect(label->getVisual()->resize_bounding_box,
|
||||
/*connect(label->getVisual()->resize_bounding_box,
|
||||
&ResizeBoundingBox::changedDelta,
|
||||
m_panel,
|
||||
&Panel::changeGeometryForSelected);
|
||||
container.ptr = label->getVisual();
|
||||
visual_uid_count++;
|
||||
container.ptr = label->getVisual();*/
|
||||
} else if (type == VisualType::Slider) {
|
||||
Slider *slider = new Slider(this);
|
||||
slider->setPanel(m_panel);
|
||||
slider->setPanel(m_panel, QPoint(400, 200));
|
||||
slider->setNodeEditor(m_nodeeditor);
|
||||
m_nodeeditor->addNode(slider);
|
||||
|
||||
connect(slider->getVisual()->resize_bounding_box,
|
||||
/*connect(slider->getVisual()->resize_bounding_box,
|
||||
&ResizeBoundingBox::changedDelta,
|
||||
m_panel,
|
||||
&Panel::changeGeometryForSelected);
|
||||
|
||||
container.ptr = slider->getVisual();
|
||||
visual_uid_count++;
|
||||
} else {
|
||||
container.ptr = nullptr;
|
||||
container.ptr = slider->getVisual();*/
|
||||
}
|
||||
|
||||
return static_cast<Visual *>(container.ptr);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include "nodes/label.h"
|
||||
#include "nodes/slider.h"
|
||||
#include "panel.h"
|
||||
#include "visual.h"
|
||||
|
||||
enum class VisualType { Parent, Test, Slider };
|
||||
|
||||
class Document : QObject
|
||||
{
|
||||
@@ -21,14 +22,11 @@ public:
|
||||
QJsonObject save();
|
||||
void load(QJsonObject);
|
||||
|
||||
Visual *createVisual(VisualType type);
|
||||
void createVisual(VisualType type);
|
||||
|
||||
DisplayMode display_mode = DisplayMode::Run;
|
||||
|
||||
private:
|
||||
unsigned int visual_uid_count = 0;
|
||||
QList<VisualContainer> visuals;
|
||||
|
||||
Panel *m_panel;
|
||||
NodeEditor *m_nodeeditor;
|
||||
};
|
||||
|
||||
@@ -40,8 +40,8 @@ void MainWindow::loadInsertVisualMenu()
|
||||
for (const VisualMenuAction &wraped_action : wrapped_actions) {
|
||||
QAction *menu_insert_action = new QAction(wraped_action.name);
|
||||
connect(menu_insert_action, &QAction::triggered, this, [this, wraped_action] {
|
||||
Visual *visual = focus_document->createVisual(wraped_action.type);
|
||||
connect(this, &MainWindow::modeChanged, visual, &Visual::setMode);
|
||||
focus_document->createVisual(wraped_action.type);
|
||||
//connect(this, &MainWindow::modeChanged, visual, &Visual::setMode);
|
||||
});
|
||||
|
||||
menu_insert_action->setText(wraped_action.name);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
qt_add_library(node STATIC
|
||||
node.h node.cpp
|
||||
interface.h interface.cpp
|
||||
nodes/visual.h nodes/visual.cpp
|
||||
nodes/label.h nodes/label.cpp
|
||||
nodes/slider.h nodes/slider.cpp
|
||||
)
|
||||
|
||||
@@ -4,14 +4,6 @@ Node::Node(QObject *parent)
|
||||
: QObject{parent}
|
||||
{}
|
||||
|
||||
void Node::setPanel(QWidget *panel_widget)
|
||||
{
|
||||
m_panel = panel_widget;
|
||||
|
||||
Visual *visual = new Visual(m_panel, 0);
|
||||
m_visual = visual;
|
||||
paintVisual(visual);
|
||||
}
|
||||
|
||||
Interface *Node::getInterface(const QString &identifier)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
#include "../panel/visual.h"
|
||||
#include "interface.h"
|
||||
|
||||
class Node : public QObject
|
||||
@@ -21,26 +20,15 @@ public:
|
||||
QList<Interface> &getInterfaces() { return m_interfaces; }
|
||||
Interface *getInterface(const QString &identifier);
|
||||
|
||||
//Pointer to the panel widgets. Needed for visual nodes to create their UI in the panel.
|
||||
void setPanel(QWidget *panel_widget);
|
||||
|
||||
//Pointer to the node editor widgets. Needed for nodes to be shown in the node editor.
|
||||
void setNodeEditor(QWidget *node_editor_widget) { m_nodeeditor = node_editor_widget; }
|
||||
|
||||
Visual *getVisual() { return m_visual; }
|
||||
|
||||
protected:
|
||||
virtual void paintVisual(Visual *) {};
|
||||
//virtual void valueChange(Interface &) ;
|
||||
|
||||
signals:
|
||||
void changedInterfaceValue(const Interface &);
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QWidget *m_panel = nullptr;
|
||||
QWidget *m_nodeeditor = nullptr;
|
||||
Visual *m_visual = nullptr;
|
||||
|
||||
QList<Interface> m_interfaces;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "label.h"
|
||||
|
||||
Label::Label(QObject *parent)
|
||||
: Node{parent}
|
||||
: Visual{parent}
|
||||
{
|
||||
setProperty("name", "Label");
|
||||
Interface text_interface = Interface(QVariant(0), InterfaceDirection::Input, "text");
|
||||
@@ -10,17 +10,13 @@ Label::Label(QObject *parent)
|
||||
getInterface("text")->setCallback([this]() { setText(); });
|
||||
}
|
||||
|
||||
void Label::paintVisual(Visual *visual)
|
||||
QWidget *Label::paintWidget(VisualContainer *visual_container)
|
||||
{
|
||||
visual->setGeometry(QRect(100, 100, 200, 50));
|
||||
visual->setMinimumSize(QSize(200, 50));
|
||||
visual->setMouseTracking(true);
|
||||
|
||||
//Create a label in the panel for this node.
|
||||
m_label = new QLabel("Label Text", visual);
|
||||
m_label = new QLabel("Label Text", visual_container);
|
||||
m_label->setGeometry(10, 10, 180, 30);
|
||||
m_label->show();
|
||||
qDebug() << "Label created";
|
||||
return m_label;
|
||||
}
|
||||
|
||||
void Label::setText()
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
#include "../node.h"
|
||||
#include "visual.h"
|
||||
|
||||
class Label : public Node
|
||||
class Label : public Visual
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
explicit Label(QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
void paintVisual(Visual *panel) override;
|
||||
QWidget *paintWidget(VisualContainer *) override;
|
||||
void setText();
|
||||
|
||||
QLabel *m_label;
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
#include "slider.h"
|
||||
|
||||
Slider::Slider(QObject *parent)
|
||||
: Node{parent}
|
||||
: Visual{parent}
|
||||
{
|
||||
setInterfaces({Interface(QVariant(0), InterfaceDirection::Output, "value")});
|
||||
setProperty("name", "Slider");
|
||||
}
|
||||
|
||||
void Slider::paintVisual(Visual *visual)
|
||||
QWidget *Slider::paintWidget(VisualContainer *visual_container)
|
||||
{
|
||||
visual->setGeometry(QRect(200, 200, 400, 100));
|
||||
visual->setMinimumSize(QSize(400, 100));
|
||||
visual->setMouseTracking(true);
|
||||
|
||||
//Create a slider in the panel for this node.
|
||||
QSlider *slider = new QSlider(visual);
|
||||
QSlider *slider = new QSlider(visual_container);
|
||||
slider->setOrientation(Qt::Horizontal);
|
||||
slider->setGeometry(10, 10, 200, 30);
|
||||
//slider->setFixedSize(200, 30);
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(100);
|
||||
slider->setValue(50);
|
||||
slider->show();
|
||||
qDebug() << "Slider created";
|
||||
connect(slider, &QSlider::valueChanged, this, &Slider::onSliderValueChanged);
|
||||
return slider;
|
||||
}
|
||||
|
||||
void Slider::onSliderValueChanged(int value)
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <QDebug>
|
||||
#include <QSlider>
|
||||
|
||||
#include "../node.h"
|
||||
#include "visual.h"
|
||||
|
||||
class Slider : public Node
|
||||
class Slider : public Visual
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -16,7 +16,7 @@ private slots:
|
||||
void onSliderValueChanged(int value);
|
||||
|
||||
private:
|
||||
void paintVisual(Visual *panel) override;
|
||||
QWidget *paintWidget(VisualContainer *) override;
|
||||
};
|
||||
|
||||
#endif // SLIDER_H
|
||||
28
src/node/nodes/visual.cpp
Normal file
28
src/node/nodes/visual.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "visual.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(visual)
|
||||
Q_LOGGING_CATEGORY(visual, "VISUAL")
|
||||
|
||||
Visual::Visual(QObject *parent)
|
||||
: Node(parent)
|
||||
{}
|
||||
|
||||
void Visual::setPanel(QWidget *panel_widget, QPoint position)
|
||||
{
|
||||
if (panel_widget) {
|
||||
m_visual_container = new VisualContainer(panel_widget);
|
||||
m_visual_container->move(position);
|
||||
m_visual_container->show();
|
||||
m_visual_widget = paintWidget(m_visual_container);
|
||||
m_visual_widget->show();
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *Visual::paintWidget(VisualContainer *visual_container)
|
||||
{
|
||||
QWidget *widget = new QWidget(visual_container);
|
||||
widget->setGeometry(50, 50, 150, 100);
|
||||
widget->setAttribute(Qt::WA_StyledBackground, true);
|
||||
widget->setStyleSheet("background-color: orange; border: 1px solid gray;");
|
||||
return widget;
|
||||
}
|
||||
26
src/node/nodes/visual.h
Normal file
26
src/node/nodes/visual.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef VISUAL_H
|
||||
#define VISUAL_H
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include "../../panel/visual_container.h"
|
||||
#include "../node.h"
|
||||
|
||||
class Visual : public Node
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Visual(QObject *parent = nullptr);
|
||||
virtual ~Visual() {};
|
||||
|
||||
void setPanel(QWidget *panel_widget, QPoint position = QPoint(0,0));
|
||||
void setPanelPosition(QPoint);
|
||||
virtual QWidget *paintWidget(VisualContainer *parent);
|
||||
|
||||
private:
|
||||
VisualContainer *m_visual_container = nullptr;
|
||||
QWidget *m_visual_widget = nullptr;
|
||||
};
|
||||
|
||||
#endif // VISUAL_H
|
||||
23
src/node/propertywindow.cpp
Normal file
23
src/node/propertywindow.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "propertywindow.h"
|
||||
|
||||
PropertyWindow::PropertyWindow(QWidget* parent, QObject* object)
|
||||
: QWidget{parent, Qt::Window}
|
||||
{
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
QFormLayout* layout = new QFormLayout(this);
|
||||
|
||||
const QMetaObject* meta = object->metaObject();
|
||||
for (int i = 0; i < meta->propertyCount(); ++i) {
|
||||
QMetaProperty prop = meta->property(i);
|
||||
QString name = prop.name();
|
||||
QVariant value = object->property(name.toLatin1());
|
||||
QLabel* nameLabel = new QLabel(name);
|
||||
QLabel* valueLabel = new QLabel(value.toString());
|
||||
layout->addRow(nameLabel, valueLabel);
|
||||
}
|
||||
|
||||
setLayout(layout);
|
||||
setWindowTitle("Properties of " + object->objectName());
|
||||
}
|
||||
18
src/node/propertywindow.h
Normal file
18
src/node/propertywindow.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef PROPERTYWINDOW_H
|
||||
#define PROPERTYWINDOW_H
|
||||
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QMetaProperty>
|
||||
#include <QWidget>
|
||||
|
||||
class PropertyWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PropertyWindow(QWidget *parent, QObject *object);
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // PROPERTYWINDOW_H
|
||||
@@ -1,7 +1,7 @@
|
||||
qt_add_library(panel STATIC
|
||||
visual.h visual.cpp
|
||||
resizeboundingbox.h resizeboundingbox.cpp
|
||||
panel.h panel.cpp
|
||||
visual_container.h visual_container.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(panel PRIVATE nodeeditor PRIVATE Qt6::Widgets)
|
||||
|
||||
@@ -8,58 +8,58 @@ Panel::Panel(QWidget *parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
|
||||
rubber_band = new QRubberBand(QRubberBand::Rectangle, this);
|
||||
m_rubber_band = new QRubberBand(QRubberBand::Rectangle, this);
|
||||
}
|
||||
|
||||
QList<Visual *> Panel::visualChildIn(QRect rect)
|
||||
QList<QWidget *> Panel::childIn(QRect section)
|
||||
{
|
||||
QList<Visual *> contained_visuals;
|
||||
foreach (Visual *visual, findChildren<Visual *>()) {
|
||||
if (rect.intersects(visual->geometry())) {
|
||||
contained_visuals.append(visual);
|
||||
QList<QWidget *> contained_widgets;
|
||||
|
||||
for (QWidget *child : findChildren<VisualContainer *>(Qt::FindDirectChildrenOnly)) {
|
||||
if (section.intersects(child->geometry()))
|
||||
contained_widgets.append(child);
|
||||
}
|
||||
}
|
||||
return contained_visuals;
|
||||
|
||||
return contained_widgets;
|
||||
}
|
||||
|
||||
Visual *Panel::visualChildAt(QPoint point)
|
||||
QWidget *Panel::childAt(QPoint point)
|
||||
{
|
||||
QList<Visual *> visuals = findChildren<Visual *>();
|
||||
QMutableListIterator<Visual *> visual(visuals);
|
||||
QWidget *top_level_widget = nullptr;
|
||||
|
||||
Visual *top_level_visual = nullptr;
|
||||
|
||||
while (visual.hasNext()) {
|
||||
if (visual.next()->geometry().contains(point)) {
|
||||
top_level_visual = visual.value();
|
||||
for (QWidget *child : findChildren<VisualContainer *>(Qt::FindDirectChildrenOnly)) {
|
||||
if (child->geometry().contains(point)) {
|
||||
top_level_widget = child;
|
||||
}
|
||||
}
|
||||
return top_level_visual;
|
||||
|
||||
return top_level_widget;
|
||||
}
|
||||
|
||||
void Panel::setMode(DisplayMode display_mode)
|
||||
{
|
||||
this->display_mode = display_mode;
|
||||
m_display_mode = display_mode;
|
||||
}
|
||||
|
||||
void Panel::triggeredAlign(AlignDirection direction)
|
||||
{
|
||||
QRect bounding_box = calculateMinimumBoundingBox(selected_visuals);
|
||||
//@TODO Proper alignment of selected QWidgets
|
||||
QRect minimal_rect = minimalSelectedRect();
|
||||
|
||||
for (Visual *visual : selected_visuals) {
|
||||
alignVisualToBoundingBox(direction, visual, bounding_box);
|
||||
for (const RbbWidgetPair pair : m_selection) {
|
||||
alignChildToMinRect(direction, pair, minimal_rect);
|
||||
}
|
||||
}
|
||||
|
||||
QRect Panel::calculateMinimumBoundingBox(const QList<Visual *> &visuals)
|
||||
QRect Panel::minimalSelectedRect()
|
||||
{
|
||||
int top = INT_MAX;
|
||||
int left = INT_MAX;
|
||||
int bottom = INT_MIN;
|
||||
int right = INT_MIN;
|
||||
|
||||
for (const Visual *visual : visuals) {
|
||||
QRect rect = visual->geometry();
|
||||
for (const RbbWidgetPair pair : m_selection) {
|
||||
QRect rect = pair.second->geometry();
|
||||
|
||||
top = std::min(top, rect.top());
|
||||
left = std::min(left, rect.left());
|
||||
@@ -70,74 +70,167 @@ QRect Panel::calculateMinimumBoundingBox(const QList<Visual *> &visuals)
|
||||
return QRect(QPoint(left, top), QPoint(right, bottom));
|
||||
}
|
||||
|
||||
void Panel::alignVisualToBoundingBox(AlignDirection direction, Visual *target, QRect bounding_box)
|
||||
void Panel::alignChildToMinRect(AlignDirection direction,
|
||||
RbbWidgetPair rbbw_pair,
|
||||
QRect minimal_rect)
|
||||
{
|
||||
QRect new_geometry = target->geometry();
|
||||
ResizeBoundingBox *rbb = rbbw_pair.first;
|
||||
QWidget *widget = rbbw_pair.second;
|
||||
QRect new_geometry = widget->geometry();
|
||||
|
||||
switch (direction) {
|
||||
case AlignDirection::Top:
|
||||
new_geometry.moveTop(bounding_box.top());
|
||||
new_geometry.moveTop(minimal_rect.top());
|
||||
break;
|
||||
case AlignDirection::Right:
|
||||
new_geometry.moveRight(bounding_box.right());
|
||||
new_geometry.moveRight(minimal_rect.right());
|
||||
break;
|
||||
case AlignDirection::Bottom:
|
||||
new_geometry.moveBottom(bounding_box.bottom());
|
||||
new_geometry.moveBottom(minimal_rect.bottom());
|
||||
break;
|
||||
case AlignDirection::Left:
|
||||
new_geometry.moveLeft(bounding_box.left());
|
||||
new_geometry.moveLeft(minimal_rect.left());
|
||||
break;
|
||||
case AlignDirection::Horizontal:
|
||||
new_geometry.moveCenter(QPoint(minimal_rect.center().x(), new_geometry.center().y()));
|
||||
break;
|
||||
case AlignDirection::Vertical:
|
||||
new_geometry.moveCenter(QPoint(new_geometry.center().x(), minimal_rect.center().y()));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
target->setGeometry(new_geometry);
|
||||
widget->setGeometry(new_geometry);
|
||||
rbb->setBoxGeometry(new_geometry);
|
||||
}
|
||||
|
||||
void Panel::select(Visual *visual)
|
||||
void Panel::select(QWidget *child)
|
||||
{
|
||||
visual->resize_bounding_box->show();
|
||||
selected_visuals.append(visual);
|
||||
ResizeBoundingBox *rbb = new ResizeBoundingBox(this);
|
||||
rbb->setBoxGeometry(child->geometry());
|
||||
rbb->show();
|
||||
connect(rbb, &ResizeBoundingBox::changedDelta, this, &Panel::changeGeometryForSelected);
|
||||
m_selection.append({rbb, child});
|
||||
//@TODO: Replace with actual name
|
||||
qInfo() << QString("Select: IMPLEMENT NAME");
|
||||
}
|
||||
|
||||
void Panel::deselectAll()
|
||||
{
|
||||
QMutableListIterator<Visual *> visual(selected_visuals);
|
||||
while (visual.hasNext()) {
|
||||
visual.next()->resize_bounding_box->hide();
|
||||
visual.remove();
|
||||
qInfo() << QString("Deselect: IMPLEMENT NAME");
|
||||
QMutableListIterator<RbbWidgetPair> i(m_selection);
|
||||
while (i.hasNext()) {
|
||||
ResizeBoundingBox *rbb = i.next().first;
|
||||
delete rbb;
|
||||
i.remove();
|
||||
}
|
||||
//@TODO: Replace with actual name
|
||||
}
|
||||
|
||||
void Panel::selectSingle(QPoint positon)
|
||||
void Panel::selectSingle(QPoint position)
|
||||
{
|
||||
Visual *top_level_visual = visualChildAt(positon);
|
||||
if (top_level_visual) {
|
||||
QWidget *top_level_child = childAt(position);
|
||||
if (top_level_child) {
|
||||
bool shift_down = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier);
|
||||
if (!shift_down)
|
||||
if (!shift_down) {
|
||||
deselectAll();
|
||||
select(top_level_visual);
|
||||
}
|
||||
select(top_level_child);
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::selectMultiple(QList<Visual *> found_visuals)
|
||||
void Panel::selectMultiple(const QList<QWidget *> &found_widgets)
|
||||
{
|
||||
if (!found_visuals.isEmpty()) {
|
||||
foreach (Visual *visual, found_visuals) {
|
||||
select(visual);
|
||||
}
|
||||
for (QWidget *widget : found_widgets) {
|
||||
select(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::changeGeometryForSelected(DragDirection active_direction, QPointF delta)
|
||||
{
|
||||
foreach (Visual *visual, selected_visuals) {
|
||||
visual->changeGeometryByDelta(active_direction, delta);
|
||||
for (RbbWidgetPair select : m_selection) {
|
||||
ResizeBoundingBox *rbb = select.first;
|
||||
QWidget *widget = select.second;
|
||||
|
||||
QRect new_geometry = calculateNewGeometry(delta,
|
||||
widget->geometry(),
|
||||
active_direction,
|
||||
widget->minimumWidth(),
|
||||
widget->minimumHeight());
|
||||
|
||||
widget->setGeometry(new_geometry);
|
||||
rbb->setBoxGeometry(new_geometry);
|
||||
}
|
||||
}
|
||||
|
||||
QRect Panel::calculateNewGeometry(
|
||||
QPointF delta, QRect old_geometry, DragDirection active_direction, int min_w, int min_h)
|
||||
{
|
||||
int initial_x = old_geometry.x();
|
||||
int initial_y = old_geometry.y();
|
||||
int initial_w = old_geometry.width();
|
||||
int initial_h = old_geometry.height();
|
||||
|
||||
int new_x = initial_x;
|
||||
int new_y = initial_y;
|
||||
int new_w = initial_w;
|
||||
int new_h = initial_h;
|
||||
|
||||
switch (active_direction) {
|
||||
case DragDirection::North: // Fixed: Bottom
|
||||
new_y = initial_y + delta.y();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::NorthEast: // Fixed: BottomLeft
|
||||
new_y = initial_y + delta.y();
|
||||
new_w = initial_w + delta.x();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::East: // Fixed: Left
|
||||
new_w = initial_w + delta.x();
|
||||
break;
|
||||
case DragDirection::SouthEast: // Fixed: TopLeft
|
||||
new_w = initial_w + delta.x();
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::South: // Fixed: Top
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::SouthWest: // Fixed: TopRight
|
||||
new_x = initial_x + delta.x();
|
||||
new_w = initial_w - delta.x();
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::West: // Fixed: Right
|
||||
new_x = initial_x + delta.x();
|
||||
new_w = initial_w - delta.x();
|
||||
break;
|
||||
case DragDirection::NorthWest: // Fixed: BottomRight
|
||||
new_x = initial_x + delta.x();
|
||||
new_y = initial_y + delta.y();
|
||||
new_w = initial_w - delta.x();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::Center:
|
||||
new_x = initial_x + delta.x();
|
||||
new_y = initial_y + delta.y();
|
||||
break;
|
||||
default: // DrageDirection::None
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_w < min_w) {
|
||||
new_w = initial_w;
|
||||
new_x = initial_x;
|
||||
}
|
||||
if (new_h < min_h) {
|
||||
new_h = initial_h;
|
||||
new_y = initial_y;
|
||||
}
|
||||
|
||||
return QRect(new_x, new_y, new_w, new_h);
|
||||
}
|
||||
|
||||
bool Panel::inMouseWiggleTolerance(QSize size)
|
||||
{
|
||||
if (size.width() > MAX_MOUSE_WIGGLE_TOLERANCE || size.height() > MAX_MOUSE_WIGGLE_TOLERANCE) {
|
||||
@@ -149,35 +242,121 @@ bool Panel::inMouseWiggleTolerance(QSize size)
|
||||
|
||||
void Panel::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (display_mode == DisplayMode::Edit) {
|
||||
origin = event->pos();
|
||||
rubber_band->setGeometry(QRect(origin, QSize(1, 1)));
|
||||
rubber_band->show();
|
||||
if (m_display_mode == DisplayMode::Edit) {
|
||||
m_origin = event->pos();
|
||||
m_rubber_band->setGeometry(QRect(m_origin, QSize(1, 1)));
|
||||
m_rubber_band->show();
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (display_mode == DisplayMode::Edit) {
|
||||
rubber_band->setGeometry(QRect(origin, event->pos()).normalized());
|
||||
if (m_display_mode == DisplayMode::Edit) {
|
||||
m_rubber_band->setGeometry(QRect(m_origin, event->pos()).normalized());
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (display_mode == DisplayMode::Edit) {
|
||||
rubber_band->hide();
|
||||
if (m_display_mode == DisplayMode::Edit) {
|
||||
m_rubber_band->hide();
|
||||
|
||||
QList<Visual *> found_visuals = visualChildIn(rubber_band->geometry());
|
||||
QList<QWidget *> found_visuals = childIn(m_rubber_band->geometry());
|
||||
if (found_visuals.isEmpty()) {
|
||||
deselectAll();
|
||||
return;
|
||||
}
|
||||
|
||||
if (inMouseWiggleTolerance(rubber_band->size())) {
|
||||
if (inMouseWiggleTolerance(m_rubber_band->size())) {
|
||||
selectSingle(event->pos());
|
||||
} else { // selction via rubber band
|
||||
selectMultiple(found_visuals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::installEventFilterRecursively(QObject *obj)
|
||||
{
|
||||
if (obj->isWidgetType()) {
|
||||
obj->installEventFilter(this);
|
||||
|
||||
// Enable mouse tracking to receive mouse move events even when no button is pressed
|
||||
if (QWidget *widget = qobject_cast<QWidget *>(obj)) {
|
||||
widget->setMouseTracking(true);
|
||||
}
|
||||
}
|
||||
|
||||
for (QObject *child : obj->children()) {
|
||||
installEventFilterRecursively(child);
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::childEvent(QChildEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ChildAdded) {
|
||||
installEventFilterRecursively(event->child());
|
||||
}
|
||||
QWidget::childEvent(event);
|
||||
}
|
||||
|
||||
bool Panel::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
// Install event filter on any newly added QWidget child
|
||||
if (event->type() == QEvent::ChildAdded) {
|
||||
QChildEvent *child_event = static_cast<QChildEvent *>(event);
|
||||
if (child_event->child()->isWidgetType()) {
|
||||
installEventFilterRecursively(child_event->child());
|
||||
}
|
||||
}
|
||||
|
||||
bool no_rbb = !qobject_cast<ResizeBoundingBox *>(watched);
|
||||
bool mouse_event = event->type() == QEvent::MouseButtonPress
|
||||
|| event->type() == QEvent::MouseMove
|
||||
|| event->type() == QEvent::MouseButtonRelease;
|
||||
bool forward_mouse_events = (m_display_mode == DisplayMode::Edit) && mouse_event && no_rbb;
|
||||
if (forward_mouse_events) {
|
||||
//@TODO: Check coordinate system of event. It might be that the coordiante system
|
||||
// of the event is relative to the child widget, not the panel.
|
||||
QMouseEvent *mapped_event = mapMouseEventToPanel(static_cast<QMouseEvent *>(event),
|
||||
qobject_cast<QWidget *>(watched));
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
mousePressEvent(mapped_event);
|
||||
delete mapped_event;
|
||||
return true;
|
||||
case QEvent::MouseMove:
|
||||
mouseMoveEvent(mapped_event);
|
||||
delete mapped_event;
|
||||
return true;
|
||||
case QEvent::MouseButtonRelease:
|
||||
mouseReleaseEvent(mapped_event);
|
||||
delete mapped_event;
|
||||
return true;
|
||||
default:
|
||||
delete mapped_event;
|
||||
break;
|
||||
}
|
||||
//@TODO: Crash on double click events
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
QMouseEvent *Panel::mapMouseEventToPanel(QMouseEvent *origin_event, QWidget *source_widget)
|
||||
{
|
||||
QPoint new_pos = origin_event->pos();
|
||||
if (source_widget && source_widget != this) {
|
||||
new_pos = source_widget->mapTo(this, origin_event->pos());
|
||||
}
|
||||
|
||||
QMouseEvent *mapped_event = new QMouseEvent(origin_event->type(),
|
||||
new_pos,
|
||||
origin_event->globalPosition(),
|
||||
origin_event->button(),
|
||||
origin_event->buttons(),
|
||||
origin_event->modifiers(),
|
||||
origin_event->pointingDevice());
|
||||
|
||||
return mapped_event;
|
||||
}
|
||||
@@ -7,48 +7,155 @@
|
||||
#include <QRubberBand>
|
||||
#include <QWidget>
|
||||
|
||||
#include "visual.h"
|
||||
#include "../node/nodes/visual.h"
|
||||
#include "resizeboundingbox.h"
|
||||
#include "visual_container.h"
|
||||
|
||||
enum class AlignDirection { Top, Right, Bottom, Left, Horizontal, Vertical };
|
||||
|
||||
enum class DisplayMode { Run, Edit };
|
||||
|
||||
const int MAX_MOUSE_WIGGLE_TOLERANCE = 5; // px of size
|
||||
|
||||
using RbbWidgetPair = std::pair<ResizeBoundingBox *, QWidget *>;
|
||||
class Panel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Panel(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
/* @brief Sets the display mode of the panel.
|
||||
*
|
||||
* This method changes the display mode of the panel to either Run or Edit.
|
||||
* In Edit mode, users can select and manipulate visual elements within the panel.
|
||||
* In Run mode, the panel behaves as a standard display without editing capabilities.
|
||||
*
|
||||
* @param display_mode The desired display mode (Run or Edit).
|
||||
*/
|
||||
void setMode(DisplayMode display_mode);
|
||||
/* @brief Align selected to direction.
|
||||
*
|
||||
* This method aligns selected children and aligns them to a direction.
|
||||
*
|
||||
* @param direction Direction to align to.
|
||||
*/
|
||||
void triggeredAlign(AlignDirection direction);
|
||||
|
||||
void changeGeometryForSelected(DragDirection, QPointF);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *) override;
|
||||
void mouseMoveEvent(QMouseEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
|
||||
public:
|
||||
void addVisual(Visual *);
|
||||
|
||||
public slots:
|
||||
void setMode(DisplayMode);
|
||||
void triggeredAlign(AlignDirection);
|
||||
void changeGeometryForSelected(DragDirection, QPointF);
|
||||
bool eventFilter(QObject *, QEvent *) override;
|
||||
void childEvent(QChildEvent *) override;
|
||||
|
||||
private:
|
||||
QPoint origin;
|
||||
QPointF last_global_position;
|
||||
bool mouse_pressed = false;
|
||||
QRubberBand *rubber_band;
|
||||
DisplayMode display_mode;
|
||||
QList<Visual *> selected_visuals;
|
||||
/**
|
||||
* @brief Makes the QWidget as selected.
|
||||
*
|
||||
* This method adds the given QWidget to the list of selected visuals.
|
||||
* It also spawns the resize bounding box for the QWidget.
|
||||
*
|
||||
* @param child The QWidget to be selected.
|
||||
*/
|
||||
void select(QWidget *child);
|
||||
|
||||
void select(Visual *);
|
||||
/**
|
||||
* @brief Deselects all selected QWidgets.
|
||||
*
|
||||
* This method clears the list of selected visuals and deletes their
|
||||
* resize bounding boxes.
|
||||
*/
|
||||
void deselectAll();
|
||||
QList<Visual *> visualChildIn(QRect);
|
||||
Visual *visualChildAt(QPoint);
|
||||
bool inMouseWiggleTolerance(QSize);
|
||||
void selectSingle(QPoint);
|
||||
void selectMultiple(QList<Visual *>);
|
||||
void alignVisualToBoundingBox(AlignDirection, Visual *, QRect);
|
||||
QRect calculateMinimumBoundingBox(const QList<Visual *> &);
|
||||
|
||||
/**
|
||||
* @brief Finds all QWidgets children within a given QRect.
|
||||
*
|
||||
* This method returns a list of QWidgets that intersect with the specified QRect.
|
||||
*
|
||||
* @param section The rectangle to check for intersecting QWidgets.
|
||||
* @return A list of QWidgets that intersect with the given QRect.
|
||||
* @see Panel::childAt(QPoint)
|
||||
*/
|
||||
QList<QWidget *> childIn(QRect section);
|
||||
|
||||
/**
|
||||
* @brief Finds a QWidget child at a given QPoint.
|
||||
*
|
||||
* This method returns the QWidget located at the specified QPoint.
|
||||
*
|
||||
* @param point The point to check for a QWidget.
|
||||
* @return The QWidget located at the given QPoint, or nullptr if none found.
|
||||
* @see Panel::childIn(QRect)
|
||||
*/
|
||||
QWidget *childAt(QPoint point);
|
||||
|
||||
/**
|
||||
* @brief Checks if mouse movement is within wiggle tolerance.
|
||||
*
|
||||
* This method determines if the mouse movement from the origin point
|
||||
* is within the defined wiggle tolerance.
|
||||
* This is useful for distinguishing between a click and a drag action.
|
||||
*
|
||||
* @param size The size representing the mouse movement delta.
|
||||
* @return True if the movement is within wiggle tolerance, false otherwise.
|
||||
*/
|
||||
bool inMouseWiggleTolerance(QSize size);
|
||||
|
||||
/**
|
||||
* @brief Selects a single QWidget with Shift key check.
|
||||
*
|
||||
* This method selects a single QWidget. If the Shift key is pressed,
|
||||
* it adds the QWidget to the current selection for multi-selection.
|
||||
* Else, it clears the current selection and selects only the given QWidget.
|
||||
*
|
||||
* @param position The point where the selection is made.
|
||||
* @see Panel::select(QWidget*)
|
||||
*/
|
||||
void selectSingle(QPoint position);
|
||||
|
||||
/**
|
||||
* @brief Selects multiple QWidgets.
|
||||
*
|
||||
* This method selects all QWidgets that intersect with the specified QRect.
|
||||
* It supports multi-selection if the Shift key is pressed.
|
||||
*
|
||||
* @param found_visuals The list of visuals to select.
|
||||
* @see Panel::select(QWidget*)
|
||||
*/
|
||||
void selectMultiple(const QList<QWidget *> &found_visuals);
|
||||
|
||||
void alignChildToMinRect(AlignDirection direction, RbbWidgetPair rbbw_pair, QRect minimal_rect);
|
||||
QRect minimalSelectedRect();
|
||||
|
||||
void installEventFilterRecursively(QObject *);
|
||||
QMouseEvent *mapMouseEventToPanel(QMouseEvent *, QWidget *);
|
||||
|
||||
/**
|
||||
* @brief Calculates a new geometry.
|
||||
*
|
||||
* This method calculates the new geometry based of the old one and the delta.
|
||||
*
|
||||
* @param delta Change in geometry.
|
||||
* @param old_geometry Geomtry before appling the delta.
|
||||
* @param active_direction Direction to drag to.
|
||||
* @param min_w Minimum width that cannot be undercut by the new geometry.
|
||||
* @param min_h Minimum height that cannot be undercut by the new geometry.
|
||||
*/
|
||||
QRect calculateNewGeometry(
|
||||
QPointF delta, QRect old_geometry, DragDirection active_direction, int min_w, int min_h);
|
||||
|
||||
QPoint m_origin;
|
||||
QPointF m_last_global_position;
|
||||
bool m_mouse_pressed = false;
|
||||
QRubberBand *m_rubber_band;
|
||||
DisplayMode m_display_mode;
|
||||
|
||||
QList<RbbWidgetPair> m_selection;
|
||||
};
|
||||
|
||||
#endif // PANEL_H
|
||||
|
||||
@@ -128,9 +128,10 @@ void ResizeBoundingBox::mouseMoveEvent(QMouseEvent *event)
|
||||
if (mouse_pressed) {
|
||||
QPointF delta = event->globalPosition() - last_global_position;
|
||||
last_global_position = event->globalPosition();
|
||||
|
||||
emit changedDelta(active_direction, delta);
|
||||
} else { // On hover
|
||||
}
|
||||
|
||||
else { // On hover
|
||||
active_direction = containesHitbox(event->pos());
|
||||
setHoverCursor(active_direction);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#include <QPainter>
|
||||
#include <QWidget>
|
||||
|
||||
const int OUTER_HITBOX_SIZE = 10;
|
||||
const QMargins WIDGET_MARGIN(20, 20, 20, 20);
|
||||
const QMargins CENTER_HITBOX_MARGIN(15, 15, 15, 15);
|
||||
static const int OUTER_HITBOX_SIZE = 10;
|
||||
static const QMargins WIDGET_MARGIN(20, 20, 20, 20);
|
||||
static const QMargins CENTER_HITBOX_MARGIN(15, 15, 15, 15);
|
||||
|
||||
enum class DragDirection {
|
||||
NorthWest,
|
||||
@@ -30,8 +30,23 @@ class ResizeBoundingBox : public QWidget
|
||||
public:
|
||||
explicit ResizeBoundingBox(QWidget *parent = nullptr);
|
||||
|
||||
void setBoxGeometry(QRect);
|
||||
void setBoxMinimumSize(QSize);
|
||||
/* @brief Sets the size of bounding box.
|
||||
|
||||
This method sets the size of the visable bounding box.
|
||||
The actual Widget has an offset, so that the mouse direction ankers are drawn correctly.
|
||||
|
||||
@param box_geometry Geometry of the bounding box.
|
||||
*/
|
||||
void setBoxGeometry(QRect box_geometry);
|
||||
|
||||
/* @brief Sets the minimum size of the bounding box.
|
||||
|
||||
This method sets the minimum size of the visable bounding box.
|
||||
The actual Widget has an offset, so that the mouse direction ankers are drawn correctly.
|
||||
|
||||
@param size Minimum size of the bounding box.
|
||||
*/
|
||||
void setBoxMinimumSize(QSize size);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *) override;
|
||||
@@ -41,7 +56,6 @@ protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
||||
signals:
|
||||
void changedGeometry(QRect);
|
||||
void changedDelta(DragDirection, QPointF);
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
#include "visual.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(visual)
|
||||
Q_LOGGING_CATEGORY(visual, "VISUAL")
|
||||
|
||||
Visual::Visual(QWidget *panel, unsigned int uid)
|
||||
: QWidget(panel)
|
||||
, m_uid(uid)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
|
||||
resize_bounding_box = new ResizeBoundingBox(panel);
|
||||
resize_bounding_box->hide();
|
||||
|
||||
setAttribute(Qt::WA_StyledBackground, true);
|
||||
setStyleSheet("background-color: lightblue; border: 1px solid blue;");
|
||||
show();
|
||||
}
|
||||
|
||||
void Visual::setGeometry(QRect geometry)
|
||||
{
|
||||
resize_bounding_box->setBoxGeometry(geometry);
|
||||
QWidget::setGeometry(geometry);
|
||||
qInfo(visual) << "Changed geometry: " << geometry;
|
||||
}
|
||||
|
||||
void Visual::setMode(DisplayMode display_mode)
|
||||
{
|
||||
m_display_mode = display_mode;
|
||||
}
|
||||
|
||||
void Visual::setMinimumSize(QSize size)
|
||||
{
|
||||
resize_bounding_box->setBoxMinimumSize(size);
|
||||
QWidget::setMinimumSize(size);
|
||||
}
|
||||
|
||||
void Visual::changeGeometry(QRect geometry)
|
||||
{
|
||||
QWidget::setGeometry(geometry);
|
||||
}
|
||||
|
||||
void Visual::changeGeometryByDelta(DragDirection active_direction, QPointF delta)
|
||||
{
|
||||
int initial_x = geometry().x();
|
||||
int initial_y = geometry().y();
|
||||
int initial_w = geometry().width();
|
||||
int initial_h = geometry().height();
|
||||
|
||||
int new_x = initial_x;
|
||||
int new_y = initial_y;
|
||||
int new_w = initial_w;
|
||||
int new_h = initial_h;
|
||||
|
||||
switch (active_direction) {
|
||||
case DragDirection::North: // Fixed: Bottom
|
||||
new_y = initial_y + delta.y();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::NorthEast: // Fixed: BottomLeft
|
||||
new_y = initial_y + delta.y();
|
||||
new_w = initial_w + delta.x();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::East: // Fixed: Left
|
||||
new_w = initial_w + delta.x();
|
||||
break;
|
||||
case DragDirection::SouthEast: // Fixed: TopLeft
|
||||
new_w = initial_w + delta.x();
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::South: // Fixed: Top
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::SouthWest: // Fixed: TopRight
|
||||
new_x = initial_x + delta.x();
|
||||
new_w = initial_w - delta.x();
|
||||
new_h = initial_h + delta.y();
|
||||
break;
|
||||
case DragDirection::West: // Fixed: Right
|
||||
new_x = initial_x + delta.x();
|
||||
new_w = initial_w - delta.x();
|
||||
break;
|
||||
case DragDirection::NorthWest: // Fixed: BottomRight
|
||||
new_x = initial_x + delta.x();
|
||||
new_y = initial_y + delta.y();
|
||||
new_w = initial_w - delta.x();
|
||||
new_h = initial_h - delta.y();
|
||||
break;
|
||||
case DragDirection::Center:
|
||||
new_x = initial_x + delta.x();
|
||||
new_y = initial_y + delta.y();
|
||||
break;
|
||||
default: // DrageDirection::None
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_w < minimumWidth()) {
|
||||
new_w = initial_w;
|
||||
new_x = initial_x;
|
||||
}
|
||||
if (new_h < minimumHeight()) {
|
||||
new_h = initial_h;
|
||||
new_y = initial_y;
|
||||
}
|
||||
|
||||
QRect new_geometry(new_x, new_y, new_w, new_h);
|
||||
|
||||
resize_bounding_box->setBoxGeometry(new_geometry);
|
||||
QWidget::setGeometry(new_geometry);
|
||||
}
|
||||
|
||||
void Visual::logInitiation()
|
||||
{
|
||||
qInfo(visual) << QString("Initiated '%1'(%2) at 0x%3")
|
||||
.arg("Implement again as property")
|
||||
.arg(QString::number(m_uid))
|
||||
.arg(reinterpret_cast<quintptr>(this), QT_POINTER_SIZE * 2, 16, QChar('0'));
|
||||
}
|
||||
|
||||
// In Edit Mode all events in PANEL_HANDLED_ON_EDIT_MODE need to get handled by the Panel
|
||||
// This could be a mouse event. The Panels needs the mouse event to handle the draging or resizing
|
||||
// of the Visual. This only works if EVERY child widget ignores the given events.
|
||||
bool Visual::checkForParentHandling(QEvent *event)
|
||||
{
|
||||
if (m_display_mode != DisplayMode::Edit) {
|
||||
//qDebug() << event;
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
for (QEvent::Type panel_handled : PANEL_HANDLED_ON_EDIT_MODE) {
|
||||
if (event->type() == panel_handled) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef VISUAL_H
|
||||
#define VISUAL_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLayout>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMouseEvent>
|
||||
#include <QMoveEvent>
|
||||
#include <QPoint>
|
||||
#include <QResizeEvent>
|
||||
#include <QSizeGrip>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
#include "resizeboundingbox.h"
|
||||
|
||||
enum class DisplayMode { Run, Edit };
|
||||
|
||||
enum class VisualType { Parent, Test, Slider };
|
||||
|
||||
const QEvent::Type PANEL_HANDLED_ON_EDIT_MODE[] = {QEvent::MouseButtonPress,
|
||||
QEvent::MouseButtonRelease,
|
||||
QEvent::MouseMove};
|
||||
|
||||
struct VisualContainer
|
||||
{
|
||||
void *ptr;
|
||||
VisualType type;
|
||||
};
|
||||
|
||||
class Visual : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Visual(QWidget *panel = nullptr, unsigned int uid = 0);
|
||||
virtual ~Visual() {};
|
||||
|
||||
void remove();
|
||||
void setGeometry(QRect);
|
||||
|
||||
ResizeBoundingBox *resize_bounding_box;
|
||||
|
||||
public slots:
|
||||
void setMode(DisplayMode);
|
||||
void changeGeometry(QRect);
|
||||
void changeGeometryByDelta(DragDirection, QPointF);
|
||||
void setMinimumSize(QSize);
|
||||
|
||||
protected:
|
||||
bool checkForParentHandling(QEvent *);
|
||||
|
||||
private:
|
||||
int m_uid;
|
||||
|
||||
void logInitiation();
|
||||
|
||||
DisplayMode m_display_mode = DisplayMode::Run;
|
||||
QPointF last_global_position;
|
||||
|
||||
void enableSizeGrip();
|
||||
void disableSizeGrip();
|
||||
};
|
||||
|
||||
#endif // VISUAL_H
|
||||
21
src/panel/visual_container.cpp
Normal file
21
src/panel/visual_container.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "visual_container.h"
|
||||
|
||||
VisualContainer::VisualContainer(QWidget *parent)
|
||||
: QWidget{parent}
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||
}
|
||||
|
||||
void VisualContainer::childEvent(QChildEvent *event)
|
||||
{
|
||||
if (event->added()) {
|
||||
QWidget *child_widget = qobject_cast<QWidget *>(event->child());
|
||||
if (child_widget) {
|
||||
layout()->addWidget(child_widget);
|
||||
}
|
||||
}
|
||||
QWidget::childEvent(event);
|
||||
}
|
||||
18
src/panel/visual_container.h
Normal file
18
src/panel/visual_container.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef VISUAL_CONTAINER_H
|
||||
#define VISUAL_CONTAINER_H
|
||||
|
||||
#include <QChildEvent>
|
||||
#include <QLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class VisualContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VisualContainer(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void childEvent(QChildEvent *) override;
|
||||
};
|
||||
|
||||
#endif // VISUAL_CONTAINER_H
|
||||
Reference in New Issue
Block a user