/* TikZiT - a GUI diagram editor for TikZ Copyright (C) 2018 Aleks Kissinger This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "style.h" #include "tikzit.h" Style *noneStyle = new Style("none", new GraphElementData()); Style *unknownStyle = new Style("unknown", new GraphElementData({GraphElementProperty("tikzit fill", "blue")})); Style *noneEdgeStyle = new Style("none", new GraphElementData({GraphElementProperty("-")})); Style::Style() : _name("none") { _data = new GraphElementData(this); } Style::Style(QString name, GraphElementData *data) : _name(name), _data(data) { _data->setParent(this); } bool Style::isNone() const { return _name == "none"; } GraphElementData *Style::data() const { return _data; } QString Style::name() const { return _name; } QColor Style::strokeColor(bool tikzitOverride) const { QString col = propertyWithDefault("draw", "black", tikzitOverride); return tikzit->colorByName(col); } QColor Style::fillColor(bool tikzitOverride) const { QString col = propertyWithDefault("fill", "white", tikzitOverride); return tikzit->colorByName(col); } QBrush Style::brush() const { return QBrush(fillColor()); } QString Style::shape(bool tikzitOverride) const { return propertyWithDefault("shape", "circle", tikzitOverride); } // TODO int Style::strokeThickness() const { return 1; } bool Style::isEdgeStyle() const { if (_data->atom("-") || _data->atom("->") || _data->atom("-|") || _data->atom("<-") || _data->atom("<->") || _data->atom("<-|") || _data->atom("|-") || _data->atom("|->") || _data->atom("|-|")) return true; else return false; } QString Style::propertyWithDefault(QString prop, QString def, bool tikzitOverride) const { if (_data == 0) return def; QString val; if (tikzitOverride) { val = _data->property("tikzit " + prop); if (val.isNull()) val = _data->property(prop); } else { val = _data->property(prop); } if (val.isNull()) val = def; return val; } QString Style::tikz() const { return "\\tikzstyle{" + _name + "}=" + _data->tikz(); } void Style::setArrowAtom(QString atom) { _data->unsetAtom("-"); _data->unsetAtom("->"); _data->unsetAtom("-|"); _data->unsetAtom("<-"); _data->unsetAtom("<->"); _data->unsetAtom("<-|"); _data->unsetAtom("|-"); _data->unsetAtom("|->"); _data->unsetAtom("|-|"); _data->setAtom(atom); } void Style::setName(const QString &name) { _name = name; } Style::ArrowTipStyle Style::arrowHead() const { if (_data->atom("->") || _data->atom("<->") || _data->atom("|->")) return Pointer; if (_data->atom("-|") || _data->atom("<-|") || _data->atom("|-|")) return Flat; return NoTip; } Style::ArrowTipStyle Style::arrowTail() const { if (_data->atom("<-") || _data->atom("<->") || _data->atom("<-|")) return Pointer; if (_data->atom("|-") || _data->atom("|->") || _data->atom("|-|")) return Flat; return NoTip; } Style::DrawStyle Style::drawStyle() const { if (_data->atom("dashed")) return Dashed; if (_data->atom("dotted")) return Dotted; return Solid; } QPen Style::pen() const { QPen p(strokeColor()); p.setWidthF((float)strokeThickness() * 2.0f); QVector 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; case Solid: break; } return p; } QPainterPath Style::path() const { QPainterPath pth; QString sh = shape(); if (sh == "rectangle") { pth.addRect(-30.0f, -30.0f, 60.0f, 60.0f); } else { // default is 'circle' pth.addEllipse(QPointF(0.0f,0.0f), 30.0f, 30.0f); } return pth; } QIcon Style::icon() const { if (!isEdgeStyle()) { // draw an icon matching the style QImage px(100,100,QImage::Format_ARGB32_Premultiplied); px.fill(Qt::transparent); QPainter painter(&px); painter.setRenderHint(QPainter::Antialiasing); QPainterPath pth = path(); pth.translate(50.0f, 50.0f); if (isNone()) { QColor c(180,180,200); painter.setPen(QPen(c)); painter.setBrush(QBrush(c)); painter.drawEllipse(QPointF(50.0f,50.0f), 3,3); QPen pen(QColor(180,180,220)); pen.setWidth(3); QVector p; p << 2.0 << 2.0; pen.setDashPattern(p); painter.setPen(pen); painter.setBrush(Qt::NoBrush); painter.drawPath(pth); } else { painter.setPen(pen()); painter.setBrush(brush()); painter.drawPath(pth); } return QIcon(QPixmap::fromImage(px)); } else { // 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); QPen pn = pen(); pn.setStyle(Qt::SolidLine); painter.setPen(pn); 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; case NoTip: 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; case NoTip: break; } return QIcon(px); } } QString Style::category() const { return propertyWithDefault("tikzit category", "", false); }