/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/profile/tabs/info_profile_tabs_strip.h" #include "ui/effects/animation_value.h" #include "ui/effects/animation_value_f.h" #include "ui/effects/ripple_animation.h" #include "ui/painter.h" #include "ui/rect.h" #include "ui/ui_utility.h" #include "styles/style_basic.h" #include "styles/style_chat_helpers.h" #include "styles/style_info.h" #include namespace Info::Profile { namespace { constexpr auto kScrollDuration = crl::time(150); constexpr auto kVerticalScrollGrace = crl::time(250); constexpr auto kVerticalScrollRest = crl::time(1000); void PaintIslandOutline( QPainter &p, const QRectF &island, float64 radius, const style::color &bg) { const auto light = (bg->c.lightness() >= 128); const auto width = light ? (0.6 * st::lineWidth) : double(st::lineWidth); if (light) { p.setPen(QPen(QColor(0, 0, 0, 20), width)); } else { auto grad = QLinearGradient(0, island.top(), 0, island.bottom()); grad.setColorAt(0., QColor(255, 255, 255, 40)); grad.setColorAt(0.5, QColor(255, 255, 255, 0)); grad.setColorAt(1., QColor(255, 255, 255, 20)); p.setPen(QPen(QBrush(grad), width)); } p.setBrush(Qt::NoBrush); const auto half = 0.5 * width; const auto stroke = light ? island.marginsAdded(QMarginsF(half, half, half, half)) : island.adjusted(half, half, -half, -half); const auto strokeRadius = light ? (radius + half) : (radius - half); p.drawRoundedRect(stroke, strokeRadius, strokeRadius); } } // namespace TabsStrip::TabsStrip(QWidget *parent, const style::ProfileTabsStrip &st) : RpWidget(parent) , _st(st) , _shadow(st::infoProfileTabsShadow) , _lastCursorPosition(QCursor::pos()) { setObjectName(u"profileTabsStrip"_q); setMouseTracking(true); style::PaletteChanged() | rpl::on_next([=] { invalidate(); }, lifetime()); } void TabsStrip::setTextContext(Ui::Text::MarkedContext context) { _context = std::move(context); _context.repaint = [=] { invalidate(); }; } void TabsStrip::invalidate() { _contentValid = false; update(); } void TabsStrip::setTabs(std::vector tabs) { const auto activeId = (_active >= 0 && _active < int(_buttons.size())) ? _buttons[_active].tab.id : QString(); setSelected(-1); const auto pillHeight = _st.height - _st.margin.top() - _st.margin.bottom(); auto buttons = std::vector