QSGNode *TabBar::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGNode *root = static_cast<QSGNode *>(oldNode);
if(!root) root = new QSGNode;
root->removeAllChildNodes();
int pos = 0;
int missingWidth = missingWidth_;
int s = 0;
if (missingWidth > 0 && current_ > s)
{
missingWidth += dotsWidth_;
for (; s < current_; ++s)
{
missingWidth -= labelsWidth_[labels_[s]] + (s == 0 ? 0 : border_);
if (missingWidth <= 0)
{
++s;
break;
}
}
}
int e = labels_.size() - 1; // this will be the last element to be drawn normally
if (missingWidth > 0 && current_ < e)
{
missingWidth += dotsWidth_;
for (; e > current_; --e)
{
missingWidth -= labelsWidth_[labels_[e]] + border_;
if (missingWidth <= 0)
{
--e;
break;
}
}
}
int additionalWidthPerLabel = (additionalWidth_ + abs(missingWidth)) / (e - s + 1);
int height = TabBar::height();
int width;
bool active;
LabelPosition position;
if (s != 0)
{
paintBox
(root, pos,
"...",
QSizeF(dotsWidth_, height
),
true, FirstLabel
);
pos += dotsWidth_ + border_;
}
for (int i = s; i <= e; i++)
{
width = labelsWidth_[labels_[i]] + additionalWidthPerLabel;
active = (i <= current_);
position = (i == 0 ? FirstLabel : (i == (labels_.size() - 1) ? LastLabel : MiddleLabel) );
paintBox
(root, pos, labels_
[i
],
QSizeF(width, height
), active, position
);
pos += width + border_;
}
if (e != (labels_.size() - 1) )
{
paintBox
(root, pos,
"...",
QSizeF(dotsWidth_, height
),
false, LastLabel
);
}
return root;
}
void TabBar
::paintBox(QSGNode
*root, qreal pos,
const QString &text,
const QSizeF &size,
bool active, LabelPosition labelPosition
) {
qreal width = size.width();
qreal height = size.height();
int arrow = height / 2;
QColor backgroundColor
= active ? activeBg_
: inactiveBg_;
QColor textColor
= active ? activeFg_
: inactiveFg_;
QSGNode *node;
QSGGeometry *geometry;
switch (labelPosition)
{
case FirstLabel:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 5);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos, 0);
geometry->vertexDataAsPoint2D()[1].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + arrow + width, height/2);
geometry->vertexDataAsPoint2D()[3].set(pos + width, height);
geometry->vertexDataAsPoint2D()[4].set(pos, height);
break;
case LastLabel:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 5);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos + arrow, height/2);
geometry->vertexDataAsPoint2D()[1].set(pos, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[3].set(pos + width, height);
geometry->vertexDataAsPoint2D()[4].set(pos, height);
break;
default:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 6);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos + arrow, height/2);
geometry->vertexDataAsPoint2D()[1].set(pos, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[3].set(pos + arrow + width, height/2);
geometry->vertexDataAsPoint2D()[4].set(pos + width, height);
geometry->vertexDataAsPoint2D()[5].set(pos, height);
break;
}
node = drawPolygon(geometry, backgroundColor);
root->appendChildNode(node);
}
QSGNode
*TabBar
::drawPolygon(QSGGeometry
*geometry,
const QColor &color
){
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(color);
QSGGeometryNode *node = new QSGGeometryNode;
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
return node;
}
QSGNode *TabBar::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGNode *root = static_cast<QSGNode *>(oldNode);
if(!root) root = new QSGNode;
root->removeAllChildNodes();
int pos = 0;
int missingWidth = missingWidth_;
int s = 0;
if (missingWidth > 0 && current_ > s)
{
missingWidth += dotsWidth_;
for (; s < current_; ++s)
{
missingWidth -= labelsWidth_[labels_[s]] + (s == 0 ? 0 : border_);
if (missingWidth <= 0)
{
++s;
break;
}
}
}
int e = labels_.size() - 1; // this will be the last element to be drawn normally
if (missingWidth > 0 && current_ < e)
{
missingWidth += dotsWidth_;
for (; e > current_; --e)
{
missingWidth -= labelsWidth_[labels_[e]] + border_;
if (missingWidth <= 0)
{
--e;
break;
}
}
}
int additionalWidthPerLabel = (additionalWidth_ + abs(missingWidth)) / (e - s + 1);
int height = TabBar::height();
int width;
bool active;
LabelPosition position;
if (s != 0)
{
paintBox(root, pos, "...", QSizeF(dotsWidth_, height), true, FirstLabel);
pos += dotsWidth_ + border_;
}
for (int i = s; i <= e; i++)
{
width = labelsWidth_[labels_[i]] + additionalWidthPerLabel;
active = (i <= current_);
position = (i == 0 ? FirstLabel : (i == (labels_.size() - 1) ? LastLabel : MiddleLabel) );
paintBox(root, pos, labels_[i], QSizeF(width, height), active, position);
pos += width + border_;
}
if (e != (labels_.size() - 1) )
{
paintBox(root, pos, "...", QSizeF(dotsWidth_, height), false, LastLabel);
}
return root;
}
void TabBar::paintBox(QSGNode *root, qreal pos, const QString &text, const QSizeF &size, bool active, LabelPosition labelPosition)
{
qreal width = size.width();
qreal height = size.height();
int arrow = height / 2;
QColor backgroundColor = active ? activeBg_ : inactiveBg_;
QColor textColor = active ? activeFg_ : inactiveFg_;
QSGNode *node;
QSGGeometry *geometry;
switch (labelPosition)
{
case FirstLabel:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 5);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos, 0);
geometry->vertexDataAsPoint2D()[1].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + arrow + width, height/2);
geometry->vertexDataAsPoint2D()[3].set(pos + width, height);
geometry->vertexDataAsPoint2D()[4].set(pos, height);
break;
case LastLabel:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 5);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos + arrow, height/2);
geometry->vertexDataAsPoint2D()[1].set(pos, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[3].set(pos + width, height);
geometry->vertexDataAsPoint2D()[4].set(pos, height);
break;
default:
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 6);
geometry->setDrawingMode(GL_TRIANGLE_FAN);
geometry->vertexDataAsPoint2D()[0].set(pos + arrow, height/2);
geometry->vertexDataAsPoint2D()[1].set(pos, 0);
geometry->vertexDataAsPoint2D()[2].set(pos + width, 0);
geometry->vertexDataAsPoint2D()[3].set(pos + arrow + width, height/2);
geometry->vertexDataAsPoint2D()[4].set(pos + width, height);
geometry->vertexDataAsPoint2D()[5].set(pos, height);
break;
}
node = drawPolygon(geometry, backgroundColor);
root->appendChildNode(node);
}
QSGNode *TabBar::drawPolygon(QSGGeometry *geometry, const QColor &color)
{
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(color);
QSGGeometryNode *node = new QSGGeometryNode;
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
return node;
}
To copy to clipboard, switch view to plain text mode
Bookmarks