#include "simulation.h"
#include "settings.h"
#include <vector>
#include <QPainter>
namespace {
const QPen wrongSimulatorPen{Qt::gray};
constexpr QMargins label_margins{5, 5, 5, 5};
constexpr QPoint box_height{5, 5};
QString wrapLabel(const QString &label)
{
constexpr int line_len_hint = 14;
QString wrapped = label.trimmed();
int prev_break = 0;
for (int curr_ix = line_len_hint; curr_ix < wrapped.length(); curr_ix += line_len_hint) {
const int not_found = -1;
int prev_space = not_found;
for (int j = curr_ix; j > prev_break; j--) {
if (wrapped[j].isSpace()) {
prev_space = j;
break;
}
}
int next_space = not_found;
for (int j = curr_ix + 1; j < wrapped.length(); j++) {
if (wrapped[j].isSpace()) {
next_space = j;
break;
}
}
if (prev_space == not_found && next_space == not_found) {
return wrapped;
}
if (prev_space != not_found && next_space != not_found) {
curr_ix = curr_ix - prev_space > next_space - curr_ix
? next_space
: prev_space;
} else if (prev_space != not_found) {
curr_ix = prev_space;
} else if (next_space != not_found) {
curr_ix = next_space;
}
wrapped[curr_ix] = '\n';
prev_break = curr_ix;
}
return wrapped;
}
QRect selectionRect(const QRect& label_bounds)
{
auto selection_rect = label_bounds.marginsAdded({3, 3, 3, 3});
selection_rect.setBottomRight(selection_rect.bottomRight() + box_height);
return selection_rect;
}
QFont labelFont()
{
auto label_font = _settings::Get().item<QFont>("font");
label_font.setWeight(QFont::DemiBold);
label_font.setPointSizeF(_settings::Get().item<double>("LargeFontSize"));
return label_font;
}
}
namespace qucs::component {
QPen SimulationComponent::pen() const
{
auto default_sim = _settings::Get().item<int>("DefaultSimulator");
auto correctSimulator = (Simulator & default_sim) == default_sim;
return correctSimulator ? QPen{color(), 2, Qt::SolidLine, Qt::FlatCap}
: wrongSimulatorPen;
}
void SimulationComponent::updateComponentBounds(const QRect& label_bounds)
{
auto sr = selectionRect(label_bounds);
x1 = sr.top();
y1 = sr.left();
x2 = sr.right();
y2 = sr.bottom();
tx = 0;
ty = y2;
}
void SimulationComponent::initSymbol(const QString &label)
{
label_text = wrapLabel(label);
updateComponentBounds(QRect{{0,0}, QFontMetrics{labelFont()}.size(0, label_text)});
}
void SimulationComponent::drawSymbol(QPainter *p)
{
const auto label_font = labelFont();
p->save();
p->setPen(pen());
p->setFont(label_font);
QRect label_bounds;
p->drawText(0, 0, 1, 1, Qt::TextDontClip, label_text, &label_bounds);
const QRect ABCD = label_bounds.marginsAdded(label_margins);
p->drawRect(ABCD);
const std::vector<QPoint> CEFGA{
ABCD.topRight(),
ABCD.topRight() + box_height,
ABCD.bottomRight() + box_height,
ABCD.bottomLeft() + box_height,
ABCD.bottomLeft()
};
p->drawPolyline(CEFGA.data(), CEFGA.size());
p->drawLine(ABCD.bottomRight(), ABCD.bottomRight() + box_height);
p->restore();
updateComponentBounds(ABCD);
}
}