diff options
-rw-r--r-- | src/data/edgestyle.cpp | 109 | ||||
-rw-r--r-- | src/data/edgestyle.h | 38 | ||||
-rw-r--r-- | src/data/nodestyle.cpp | 80 | ||||
-rw-r--r-- | src/data/nodestyle.h | 21 | ||||
-rw-r--r-- | src/data/style.cpp | 60 | ||||
-rw-r--r-- | src/data/style.h | 36 | ||||
-rw-r--r-- | src/data/tikzlexer.l | 9 | ||||
-rw-r--r-- | src/data/tikzstyles.cpp | 27 | ||||
-rw-r--r-- | src/data/tikzstyles.h | 4 | ||||
-rw-r--r-- | src/gui/stylepalette.cpp (renamed from stylepalette.cpp) | 55 | ||||
-rw-r--r-- | src/gui/stylepalette.h (renamed from stylepalette.h) | 12 | ||||
-rw-r--r-- | src/gui/stylepalette.ui (renamed from stylepalette.ui) | 10 | ||||
-rw-r--r-- | src/gui/tikzscene.cpp | 2 | ||||
-rw-r--r-- | src/gui/tikzview.cpp | 2 | ||||
-rw-r--r-- | tikzit.pro | 18 |
15 files changed, 359 insertions, 124 deletions
diff --git a/src/data/edgestyle.cpp b/src/data/edgestyle.cpp new file mode 100644 index 0000000..d366946 --- /dev/null +++ b/src/data/edgestyle.cpp @@ -0,0 +1,109 @@ +#include "edgestyle.h" + +#include <QPainter> +#include <QPixmap> + +EdgeStyle *noneEdgeStyle = new EdgeStyle(); + +EdgeStyle::EdgeStyle() : Style() +{ +} + +EdgeStyle::EdgeStyle(QString name, GraphElementData *data) : Style(name, data) +{ +} + +EdgeStyle::ArrowTipStyle EdgeStyle::arrowHead() const +{ + if (_data == 0) return NoTip; + + if (_data->atom("->") || _data->atom("<->") || _data->atom("|->")) return Pointer; + if (_data->atom("-|") || _data->atom("<-|") || _data->atom("|-|")) return Flat; + return NoTip; +} + +EdgeStyle::ArrowTipStyle EdgeStyle::arrowTail() const +{ + if (_data == 0) return NoTip; + if (_data->atom("<-") || _data->atom("<->") || _data->atom("<-|")) return Pointer; + if (_data->atom("|-") || _data->atom("|->") || _data->atom("|-|")) return Flat; + return NoTip; +} + +EdgeStyle::DrawStyle EdgeStyle::drawStyle() const +{ + if (_data == 0) return Solid; + if (_data->atom("dashed")) return Dashed; + if (_data->atom("dotted")) return Dotted; + return Solid; +} + +QPen EdgeStyle::pen() const +{ + QPen p(strokeColor()); + p.setWidthF((float)strokeThickness() * 3.0f); + + QVector<qreal> pat; + switch (drawStyle()) { + case Dashed: + pat << 3.0 << 3.0; + p.setDashPattern(pat); + break; + case Dotted: + pat << 1.0 << 1.0; + p.setDashPattern(pat); + break; + } + + return p; +} + +QPainterPath EdgeStyle::path() const +{ + return QPainterPath(); +} + +QPainterPath EdgeStyle::palettePath() const +{ + return QPainterPath(); +} + +QIcon EdgeStyle::icon() const +{ + // draw an icon matching the style + QPixmap px(100,100); + px.fill(Qt::transparent); + QPainter painter(&px); + + if (_data == 0) { + QPen pen(Qt::black); + pen.setWidth(3); + } else { + painter.setPen(pen()); + } + + painter.drawLine(10, 50, 90, 50); + + switch (arrowHead()) { + case Pointer: + painter.drawLine(90,50,80,40); + painter.drawLine(90,50,80,60); + break; + case Flat: + painter.drawLine(90,40,90,60); + break; + } + + switch (arrowTail()) { + case Pointer: + painter.drawLine(10,50,20,40); + painter.drawLine(10,50,20,60); + break; + case Flat: + painter.drawLine(10,40,10,60); + break; + } + + + return QIcon(px); +} diff --git a/src/data/edgestyle.h b/src/data/edgestyle.h new file mode 100644 index 0000000..6b0c3bb --- /dev/null +++ b/src/data/edgestyle.h @@ -0,0 +1,38 @@ +#ifndef EDGESTYLE_H +#define EDGESTYLE_H + +#include "style.h" + +#include <QColor> +#include <QPen> +#include <QBrush> +#include <QPainterPath> +#include <QIcon> + +class EdgeStyle : public Style +{ +public: + EdgeStyle(); + EdgeStyle(QString name, GraphElementData *data); + + enum ArrowTipStyle { + Flat, Pointer, NoTip + }; + + enum DrawStyle { + Solid, Dotted, Dashed + }; + + ArrowTipStyle arrowHead() const; + ArrowTipStyle arrowTail() const; + DrawStyle drawStyle() const; + + QPen pen() const; + QPainterPath path() const override; + QPainterPath palettePath() const override; + QIcon icon() const override; +}; + +extern EdgeStyle *noneEdgeStyle; + +#endif // EDGESTYLE_H diff --git a/src/data/nodestyle.cpp b/src/data/nodestyle.cpp index b3d72fb..3f2c921 100644 --- a/src/data/nodestyle.cpp +++ b/src/data/nodestyle.cpp @@ -3,91 +3,43 @@ NodeStyle *noneStyle = new NodeStyle(); -NodeStyle::NodeStyle() : _name("none"), _data(0) +NodeStyle::NodeStyle() : Style() { } -NodeStyle::NodeStyle(QString name, GraphElementData *data): _name(name), _data(data) +NodeStyle::NodeStyle(QString name, GraphElementData *data): Style(name, data) { } -bool NodeStyle::isNone() { return _data == 0; } - -GraphElementData *NodeStyle::data() const -{ - return _data; -} - -QString NodeStyle::name() const -{ - return _name; -} - -NodeStyle::Shape NodeStyle::shape() const -{ - if (_data == 0) return NodeStyle::Circle; - - QString sh = _data->property("shape"); - if (sh.isNull()) return NodeStyle::Circle; - else if (sh == "circle") return NodeStyle::Circle; - else if (sh == "rectangle") return NodeStyle::Rectangle; - else return NodeStyle::Circle; -} - QColor NodeStyle::fillColor() const { if (_data == 0) return Qt::white; - QString col = _data->property("fill"); - - if (col.isNull()) { - return QColor(Qt::white); - } else { - QColor namedColor(col); - if (namedColor.isValid()) { - return namedColor; - } else { - // TODO: read RGB colors - return QColor(Qt::white); - } - } -} - -QColor NodeStyle::strokeColor() const -{ - if (_data == 0) return Qt::black; + QString col = propertyWithDefault("fill", "white"); - QString col = _data->property("draw"); - - if (col.isNull()) { - return QColor(Qt::black); + QColor namedColor(col); + if (namedColor.isValid()) { + return namedColor; } else { - QColor namedColor(col); - if (namedColor.isValid()) { - return namedColor; - } else { - // TODO: read RGB colors - return QColor(Qt::white); - } + // TODO: read RGB colors + return QColor(Qt::white); } } -int NodeStyle::strokeThickness() const +QBrush NodeStyle::brush() const { - return 1; + return QBrush(fillColor()); } -QPen NodeStyle::pen() const +NodeStyle::Shape NodeStyle::shape() const { - QPen p(strokeColor()); - p.setWidthF((float)strokeThickness() * 3.0f); - return p; -} + if (_data == 0) return NodeStyle::Circle; -QBrush NodeStyle::brush() const -{ - return QBrush(fillColor()); + QString sh = propertyWithDefault("shape", "circle"); + if (sh == "circle") return NodeStyle::Circle; + else if (sh == "rectangle") return NodeStyle::Rectangle; + else return NodeStyle::Circle; } QPainterPath NodeStyle::path() const diff --git a/src/data/nodestyle.h b/src/data/nodestyle.h index 0b9f282..4b48bb3 100644 --- a/src/data/nodestyle.h +++ b/src/data/nodestyle.h @@ -1,7 +1,7 @@ #ifndef NODESTYLE_H #define NODESTYLE_H -#include "graphelementdata.h" +#include "style.h" #include <QColor> #include <QPen> @@ -9,7 +9,7 @@ #include <QPainterPath> #include <QIcon> -class NodeStyle +class NodeStyle : public Style { public: enum Shape { @@ -18,23 +18,14 @@ public: NodeStyle(); NodeStyle(QString name, GraphElementData *data); - bool isNone(); - GraphElementData *data() const; - QString name() const; - Shape shape() const; QColor fillColor() const; - QColor strokeColor() const; - int strokeThickness() const; - - QPen pen() const; QBrush brush() const; QPainterPath path() const; - QPainterPath palettePath() const; - QIcon icon() const; -private: - QString _name; - GraphElementData *_data; + Shape shape() const; + + QPainterPath palettePath() const override; + QIcon icon() const override; }; extern NodeStyle *noneStyle; diff --git a/src/data/style.cpp b/src/data/style.cpp new file mode 100644 index 0000000..927271c --- /dev/null +++ b/src/data/style.cpp @@ -0,0 +1,60 @@ +#include "style.h" + +Style::Style() : _name("none"), _data(0) +{ +} + +Style::Style(QString name, GraphElementData *data) : _name(name), _data(data) +{ +} + +bool Style::isNone() +{ + return _data == 0; +} + +GraphElementData *Style::data() const +{ + return _data; +} + +QString Style::name() const +{ + return _name; +} + +QColor Style::strokeColor() const +{ + if (_data == 0) return Qt::black; + + QString col = propertyWithDefault("draw", "black"); + + QColor namedColor(col); + if (namedColor.isValid()) { + return namedColor; + } else { + // TODO: read RGB colors + return QColor(Qt::black); + } +} + +// TODO +int Style::strokeThickness() const +{ + return 1; +} + +QPen Style::pen() const +{ + QPen p(strokeColor()); + p.setWidthF((float)strokeThickness() * 3.0f); + return p; +} + +QString Style::propertyWithDefault(QString prop, QString def) const +{ + QString val = _data->property("tikzit " + prop); + if (val.isNull()) val = _data->property(prop); + if (val.isNull()) val = def; + return val; +} diff --git a/src/data/style.h b/src/data/style.h new file mode 100644 index 0000000..9d58ebe --- /dev/null +++ b/src/data/style.h @@ -0,0 +1,36 @@ +#ifndef STYLE_H +#define STYLE_H + + +#include "graphelementdata.h" + +#include <QColor> +#include <QPen> +#include <QBrush> +#include <QPainterPath> +#include <QIcon> + +class Style +{ +public: + Style(); + Style(QString name, GraphElementData *data); + bool isNone(); + + // properties that both edges and nodes have + GraphElementData *data() const; + QString name() const; + QColor strokeColor() const; + int strokeThickness() const; + + // methods that are implemented differently for edges and nodes + virtual QPen pen() const; + virtual QPainterPath path() const = 0; + virtual QPainterPath palettePath() const = 0; + virtual QIcon icon() const = 0; +protected: + QString propertyWithDefault(QString prop, QString def) const; + QString _name; + GraphElementData *_data; +}; +#endif // STYLE_H diff --git a/src/data/tikzlexer.l b/src/data/tikzlexer.l index d90ad4b..45494d2 100644 --- a/src/data/tikzlexer.l +++ b/src/data/tikzlexer.l @@ -65,6 +65,7 @@ FLOAT \-?[0-9]*(\.[0-9]+)? yylloc->first_column = yylloc->last_column = 0; } <INITIAL,xcoord,ycoord,props,noderef>[\t ]+ { } +<INITIAL,xcoord,ycoord,props,noderef>%.*$ { } \\begin\{tikzpicture\} { return BEGIN_TIKZPICTURE_CMD; } \\end\{tikzpicture\} { return END_TIKZPICTURE_CMD; } @@ -74,12 +75,12 @@ FLOAT \-?[0-9]*(\.[0-9]+)? \\draw { return DRAW_CMD; } \\node { return NODE_CMD; } \\path { return PATH_CMD; } -rectangle { return RECTANGLE; } -node { return NODE; } -at { return AT; } -to { return TO; } ; { return SEMICOLON; } = { return EQUALS; } +<INITIAL>rectangle { return RECTANGLE; } +<INITIAL>node { return NODE; } +<INITIAL>at { return AT; } +<INITIAL>to { return TO; } \([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) { yylloc->last_column = yylloc->first_column + 1; diff --git a/src/data/tikzstyles.cpp b/src/data/tikzstyles.cpp index 186e19b..c198412 100644 --- a/src/data/tikzstyles.cpp +++ b/src/data/tikzstyles.cpp @@ -12,7 +12,14 @@ NodeStyle *TikzStyles::nodeStyle(QString name) const { foreach (NodeStyle *s , _nodeStyles) if (s->name() == name) return s; - return noneStyle; //NodeStyle(name, NodeShape::Circle, Qt::white); + return noneStyle; +} + +EdgeStyle *TikzStyles::edgeStyle(QString name) const +{ + foreach (EdgeStyle *s , _edgeStyles) + if (s->name() == name) return s; + return noneEdgeStyle; } QVector<NodeStyle *> TikzStyles::nodeStyles() const @@ -23,14 +30,24 @@ QVector<NodeStyle *> TikzStyles::nodeStyles() const void TikzStyles::clear() { _nodeStyles.clear(); + _edgeStyles.clear(); +} + +QVector<EdgeStyle *> TikzStyles::edgeStyles() const +{ + return _edgeStyles; } void TikzStyles::addStyle(QString name, GraphElementData *data) { - //qDebug() << "got style {" << name << "} = [" << data << "]"; - if (!data->property("fill").isNull()) { // node style + if (data->atom("-") || data->atom("->") || data->atom("-|") || + data->atom("<-") || data->atom("<->") || data->atom("<-|") || + data->atom("|-") || data->atom("|->") || data->atom("|-|")) + { // edge style + qDebug() << "got edge style" << name; + _edgeStyles << new EdgeStyle(name, data); + } else { // node style + qDebug() << "got node style" << name; _nodeStyles << new NodeStyle(name, data); - } else { // edge style - // TODO: edge styles } } diff --git a/src/data/tikzstyles.h b/src/data/tikzstyles.h index eaf7e64..4cd7d6e 100644 --- a/src/data/tikzstyles.h +++ b/src/data/tikzstyles.h @@ -3,6 +3,7 @@ #include "graphelementdata.h" #include "nodestyle.h" +#include "edgestyle.h" #include <QObject> #include <QString> @@ -15,7 +16,9 @@ public: void addStyle(QString name, GraphElementData *data); NodeStyle *nodeStyle(QString name) const; + EdgeStyle *edgeStyle(QString name) const; QVector<NodeStyle *> nodeStyles() const; + QVector<EdgeStyle *> edgeStyles() const; void clear(); signals: @@ -24,6 +27,7 @@ public slots: private: QVector<NodeStyle*> _nodeStyles; + QVector<EdgeStyle*> _edgeStyles; }; #endif // PROJECT_H diff --git a/stylepalette.cpp b/src/gui/stylepalette.cpp index c599750..f7c17c0 100644 --- a/stylepalette.cpp +++ b/src/gui/stylepalette.cpp @@ -22,15 +22,22 @@ StylePalette::StylePalette(QWidget *parent) : // restoreGeometry(geom.toByteArray()); // } - _model = new QStandardItemModel(this); - ui->styleListView->setModel(_model); + _nodeModel = new QStandardItemModel(this); + _edgeModel = new QStandardItemModel(this); + + ui->styleListView->setModel(_nodeModel); ui->styleListView->setViewMode(QListView::IconMode); ui->styleListView->setMovement(QListView::Static); ui->styleListView->setGridSize(QSize(70,40)); + ui->edgeStyleListView->setModel(_edgeModel); + ui->edgeStyleListView->setViewMode(QListView::IconMode); + ui->edgeStyleListView->setMovement(QListView::Static); + ui->edgeStyleListView->setGridSize(QSize(70,40)); + reloadStyles(); - connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( itemDoubleClicked(const QModelIndex&)) ); + connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( nodeStyleDoubleClicked(const QModelIndex&)) ); } StylePalette::~StylePalette() @@ -40,34 +47,45 @@ StylePalette::~StylePalette() void StylePalette::reloadStyles() { - _model->clear(); + _nodeModel->clear(); + _edgeModel->clear(); QString f = tikzit->styleFile(); - // ui->styleFile->setText(f); QStandardItem *it; - //QSize sz(60,60); it = new QStandardItem(noneStyle->icon(), noneStyle->name()); it->setEditable(false); it->setData(noneStyle->name()); - _model->appendRow(it); + _nodeModel->appendRow(it); foreach(NodeStyle *ns, tikzit->styles()->nodeStyles()) { it = new QStandardItem(ns->icon(), ns->name()); it->setEditable(false); it->setData(ns->name()); - _model->appendRow(it); + _nodeModel->appendRow(it); + } + + it = new QStandardItem(noneEdgeStyle->icon(), noneEdgeStyle->name()); + it->setEditable(false); + it->setData(noneEdgeStyle->name()); + _edgeModel->appendRow(it); + + foreach(EdgeStyle *es, tikzit->styles()->edgeStyles()) { + it = new QStandardItem(es->icon(), es->name()); + it->setEditable(false); + it->setData(es->name()); + _edgeModel->appendRow(it); } } -void StylePalette::changeStyle(int increment) +void StylePalette::changeNodeStyle(int increment) { QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes(); int row = 0; if (!i.isEmpty()) { - int row = (i[0].row()+increment)%_model->rowCount(); - if (row < 0) row += _model->rowCount(); + int row = (i[0].row()+increment)%_nodeModel->rowCount(); + if (row < 0) row += _nodeModel->rowCount(); } QModelIndex i1 = ui->styleListView->rootIndex().child(row, 0); @@ -75,14 +93,14 @@ void StylePalette::changeStyle(int increment) ui->styleListView->scrollTo(i1); } -void StylePalette::nextStyle() +void StylePalette::nextNodeStyle() { - changeStyle(1); + changeNodeStyle(1); } -void StylePalette::previousStyle() +void StylePalette::previousNodeStyle() { - changeStyle(-1); + changeNodeStyle(-1); } QString StylePalette::activeNodeStyleName() @@ -96,11 +114,16 @@ QString StylePalette::activeNodeStyleName() } } -void StylePalette::itemDoubleClicked(const QModelIndex &index) +void StylePalette::nodeStyleDoubleClicked(const QModelIndex &index) { tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes(); } +void StylePalette::edgeStyleDoubleClicked(const QModelIndex &index) +{ + // TODO +} + void StylePalette::on_buttonOpenTikzstyles_clicked() { tikzit->openTikzStyles(); diff --git a/stylepalette.h b/src/gui/stylepalette.h index a465034..8663cc4 100644 --- a/stylepalette.h +++ b/src/gui/stylepalette.h @@ -16,22 +16,24 @@ public: explicit StylePalette(QWidget *parent = 0); ~StylePalette(); void reloadStyles(); - void nextStyle(); - void previousStyle(); + void nextNodeStyle(); + void previousNodeStyle(); QString activeNodeStyleName(); public slots: - void itemDoubleClicked(const QModelIndex &index); + void nodeStyleDoubleClicked(const QModelIndex &index); + void edgeStyleDoubleClicked(const QModelIndex &index); void on_buttonOpenTikzstyles_clicked(); void on_buttonRefreshTikzstyles_clicked(); //void on_buttonApplyNodeStyle_clicked(); private: - void changeStyle(int increment); + void changeNodeStyle(int increment); Ui::StylePalette *ui; - QStandardItemModel *_model; + QStandardItemModel *_nodeModel; + QStandardItemModel *_edgeModel; protected: void closeEvent(QCloseEvent *event) override; diff --git a/stylepalette.ui b/src/gui/stylepalette.ui index 3362ce2..4f5b58d 100644 --- a/stylepalette.ui +++ b/src/gui/stylepalette.ui @@ -19,7 +19,7 @@ <property name="minimumSize"> <size> <width>88</width> - <height>0</height> + <height>191</height> </size> </property> <property name="maximumSize"> @@ -66,7 +66,7 @@ <string/> </property> <property name="icon"> - <iconset resource="tikzit.qrc"> + <iconset resource="../../tikzit.qrc"> <normaloff>:/images/document-open.svg</normaloff>:/images/document-open.svg</iconset> </property> </widget> @@ -77,7 +77,7 @@ <string/> </property> <property name="icon"> - <iconset resource="tikzit.qrc"> + <iconset resource="../../tikzit.qrc"> <normaloff>:/images/refresh.svg</normaloff>:/images/refresh.svg</iconset> </property> </widget> @@ -108,13 +108,13 @@ </widget> </item> <item> - <widget class="QListView" name="listView"/> + <widget class="QListView" name="edgeStyleListView"/> </item> </layout> </widget> </widget> <resources> - <include location="tikzit.qrc"/> + <include location="../../tikzit.qrc"/> </resources> <connections/> </ui> diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp index 2a9b2fb..9b6c2d6 100644 --- a/src/gui/tikzscene.cpp +++ b/src/gui/tikzscene.cpp @@ -463,7 +463,7 @@ void TikzScene::keyPressEvent(QKeyEvent *event) if (event->key() == Qt::Key_QuoteLeft) { capture = true; - _styles->nextStyle(); + _styles->nextNodeStyle(); } if (event->modifiers() & Qt::ControlModifier) { diff --git a/src/gui/tikzview.cpp b/src/gui/tikzview.cpp index 047ef50..9997106 100644 --- a/src/gui/tikzview.cpp +++ b/src/gui/tikzview.cpp @@ -6,7 +6,7 @@ TikzView::TikzView(QWidget *parent) : QGraphicsView(parent) { - //setRenderHint(QPainter::Antialiasing); + setRenderHint(QPainter::Antialiasing); //setDragMode(QGraphicsView::RubberBandDrag); _scale = 1.0f; @@ -4,11 +4,9 @@ # #------------------------------------------------- -QT += core gui +QT += core gui widgets CONFIG += testcase -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - TARGET = tikzit TEMPLATE = app @@ -48,9 +46,11 @@ SOURCES += src/gui/mainwindow.cpp \ src/gui/undocommands.cpp \ src/gui/mainmenu.cpp \ src/util.cpp \ - stylepalette.cpp \ + src/gui/stylepalette.cpp \ src/data/tikzassembler.cpp \ - src/data/tikzstyles.cpp + src/data/tikzstyles.cpp \ + src/data/edgestyle.cpp \ + src/data/style.cpp HEADERS += src/gui/mainwindow.h \ src/gui/toolpalette.h \ @@ -72,14 +72,16 @@ HEADERS += src/gui/mainwindow.h \ src/gui/undocommands.h \ src/gui/mainmenu.h \ src/util.h \ - stylepalette.h \ + src/gui/stylepalette.h \ src/data/tikzassembler.h \ - src/data/tikzstyles.h + src/data/tikzstyles.h \ + src/data/edgestyle.h \ + src/data/style.h FORMS += src/gui/mainwindow.ui \ src/gui/propertypalette.ui \ src/gui/mainmenu.ui \ - stylepalette.ui + src/gui/stylepalette.ui INCLUDEPATH += src src/gui src/data |