#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include #include #include #include namespace Ui { class MainWindow; } class ParamList : public QMap { public: int number (QString key, int default_value = 0); }; class ColorButton : public QToolButton { private : QString name; QColor color; public : ColorButton (QString s); protected: void mousePressEvent(QMouseEvent *event); }; class Common : private QObject { Q_OBJECT public : ParamList params; }; class Rectangle : public QGraphicsRectItem, public Common { protected: void dragEnterEvent (QGraphicsSceneDragDropEvent *event); void dropEvent (QGraphicsSceneDragDropEvent *event); public: Rectangle (); }; class Ellipse : public QGraphicsEllipseItem, public Common { protected: void dragEnterEvent (QGraphicsSceneDragDropEvent *event); void dropEvent (QGraphicsSceneDragDropEvent *event); public: Ellipse (); }; class TreeNode : public QTreeWidgetItem { public: Common * common; QAbstractGraphicsShapeItem * shape; TreeNode () : common (NULL), shape (NULL) { } }; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void readFile(QString fileName); Rectangle * createRectangle (TreeNode * node, QGraphicsItem * target, ParamList param); Ellipse * createEllipse (TreeNode * node, QGraphicsItem * target, ParamList param); void modifyShape (QGraphicsItem * target, QAbstractGraphicsShapeItem * shape, ParamList param); private slots: void on_treeWidget_itemClicked(QTreeWidgetItem *item, int column); void on_tableWidget_itemChanged(QTableWidgetItem *item); private: Ui::MainWindow * ui; QGraphicsScene * scene; Common * current_element; }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include int ParamList::number(QString key, int default_value) { QString s = this->value (key); bool ok; int n = s.toInt (&ok); if (!ok) n = default_value; return n; } /* Color Button */ ColorButton::ColorButton(QString s) : name (s), color (QColor (s)) { setText (s); setToolTip (s); QPixmap p (24, 24); p.fill (QColor (0, 0, 0, 0)); QPainter m (&p); m.setPen (color); m.setBrush (color); m.drawEllipse (2, 2, 20, 20); QIcon icon (p); setIcon (icon); } void ColorButton::mousePressEvent(QMouseEvent *event) { QDrag * drag = new QDrag (this); QMimeData * data = new QMimeData (); data->setText (name); data->setColorData (color); drag->setMimeData(data); QPixmap p = this->icon().pixmap(12, 12); drag->setPixmap(p); drag->start(Qt::CopyAction | Qt::MoveAction); }; /* Rectangle */ void Rectangle::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { event->setAccepted(true); } void Rectangle::dropEvent(QGraphicsSceneDragDropEvent *event) { const QMimeData * data = event->mimeData(); if (data->hasColor()) { QColor c = data->colorData().value (); if (event->proposedAction() == Qt::MoveAction) /* shift */ setPen (c); else setBrush (c); } } Rectangle::Rectangle() { setAcceptDrops(true); } /* Ellipse */ void Ellipse::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { event->setAccepted(true); } void Ellipse::dropEvent(QGraphicsSceneDragDropEvent *event) { const QMimeData * data = event->mimeData(); if (data->hasColor()) { QColor c = data->colorData().value (); if (event->proposedAction() == Qt::MoveAction) /* shift */ setPen (c); else setBrush (c); } } Ellipse::Ellipse() { setAcceptDrops(true); } /* MainWindow */ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), current_element (NULL) { ui->setupUi(this); QList names; names << "red" << "blue" << "green" << "yellow" << "orange"; for (auto name : names) { ColorButton * b = new ColorButton (name); ui->mainToolBar->addWidget (b); } scene = new QGraphicsScene; ui->graphicsView->setScene (scene); // scene->addLine (0, 0, 100, 100, QColor ("blue")); scene->setSceneRect (0, 0, 1024, 800); readFile ("../xml/data.xml"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::readFile (QString fileName) { QFile file (fileName); if (file.open (QFile::ReadOnly | QFile::Text )) { QTreeWidgetItem * branch = ui->treeWidget->invisibleRootItem(); QGraphicsItem * target = NULL; QXmlStreamReader reader (&file); while (! reader.atEnd()) { if (reader.isStartElement()) { QString s = reader.name().toString(); TreeNode * item = new TreeNode; item->setText (0, s); item->setForeground (0, QColor ("blue")); branch->addChild (item); branch = item; ParamList list; // for (QXmlStreamAttribute a : reader.attributes()) for (auto a : reader.attributes()) { QString t = a.name().toString(); QString v = a.value().toString(); /* auto node = new QTreeWidgetItem; node->setText (0, t + " = " + v); node->setForeground (0, QColor ("green")); item->addChild (node); */ // list.insert(t, v); list [t] = v; } if (s == "rectangle") target = createRectangle (item, target, list); else if (s == "ellipse") target = createEllipse (item, target, list); } else if (reader.isCharacters()) { QString s = reader.text().toString().simplified(); if (s != "") { QTreeWidgetItem * item = new QTreeWidgetItem; item->setText (0, s); item->setForeground (0, QColor ("orange")); branch->addChild (item); } } else if (reader.isEndElement()) { branch = branch->parent(); QString s = reader.name().toString(); if (s == "rectangle" || s == "ellipse") target = target->parentItem (); } reader.readNext(); } ui->treeWidget->expandAll(); } } Rectangle * MainWindow::createRectangle (TreeNode * node, QGraphicsItem * target, ParamList list) { Rectangle * shape = new Rectangle; shape->params = list; node->common = shape; node->shape = shape; int w = list.number ("w", 100); int h = list.number ("h", 40); shape->setRect (0, 0, w, h); modifyShape (target, shape, list); return shape; } Ellipse * MainWindow::createEllipse (TreeNode * node, QGraphicsItem * target, ParamList list) { Ellipse * shape = new Ellipse; shape->params = list; node->common = shape; node->shape = shape; int w = list.number ("w", 10); int h = list.number ("h", 10); shape->setRect (0, 0, w, h); modifyShape (target, shape, list); return shape; } void MainWindow::modifyShape (QGraphicsItem * target, QAbstractGraphicsShapeItem * shape, ParamList list) { int x = list.number ("x", 20); int y = list.number ("y", 20); shape->setPos (x, y); QString pen = list ["pen"]; if (pen != "") shape->setPen (QColor (pen)); QString brush = list ["brush"]; if (brush != "") shape->setBrush (QColor (brush)); shape->setFlag (QGraphicsItem::ItemIsMovable); shape->setFlag (QGraphicsItem::ItemIsSelectable); if (target == NULL) scene->addItem (shape); else shape->setParentItem (target); } void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column) { TreeNode * node = dynamic_cast (item); if (node != NULL && node->common != NULL ) { current_element = NULL; ui->statusBar->showMessage ("click"); ui->tableWidget->clear (); ui->tableWidget->setColumnCount (2); int cnt = 0; QMapIterator iter (node->common->params); while (iter.hasNext()) { iter.next(); QString name = iter.key (); QString value = iter.value (); ui->tableWidget->setRowCount(cnt+1); QTableWidgetItem * field = new QTableWidgetItem; field->setText (name); ui->tableWidget->setItem (cnt, 0, field); field = new QTableWidgetItem; field->setText (value); ui->tableWidget->setItem (cnt, 1, field); if (name == "pen" or name == "brush") field->setData(Qt::DecorationRole, QColor (value)); field->setData(Qt::UserRole, name); cnt ++; } current_element = node->common; } } int conv (QString s, int default_value) { bool ok; int n = s.toInt (&ok); if (!ok) n = default_value; return n; } void MainWindow::on_tableWidget_itemChanged(QTableWidgetItem *item) { QString name = item->data (Qt::UserRole).toString (); QString value = item->text (); if (name != "" && current_element != NULL) { ui->statusBar->showMessage ("update " + name + " = " + value); Common * common = current_element; QAbstractGraphicsShapeItem * shape = dynamic_cast (common); if (name == "pen" && shape != NULL) shape->setPen (QColor (value)); if (name == "brush" && shape != NULL) shape->setBrush (QColor (value)); if (name == "pen" || name == "brush") item->setData(Qt::DecorationRole, QColor (value)); if (name == "x") shape->setX (conv (value, 0)); if (name == "y") shape->setY (conv (value, 0)); if (name == "w" || name == "h") { Rectangle * r = dynamic_cast (shape); Ellipse * e = dynamic_cast (shape); QRectF size; if (r != NULL) size = r->rect(); if (e != NULL) size = e->rect(); int v = conv (value, 20); if (name == "w") size.setWidth (v); else size.setHeight (v); if (r != NULL) r->setRect (size); if (e != NULL) e->setRect (size); } common->params[name] = value; } }