diff --git a/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp b/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp index e257b81aa..a24d18a8a 100644 --- a/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp +++ b/Telegram/SourceFiles/ui/widgets/discrete_sliders.cpp @@ -103,6 +103,15 @@ void DiscreteSlider::enumerateSections(Lambda callback) { } } +template +void DiscreteSlider::enumerateSections(Lambda callback) const { + for (auto §ion : _sections) { + if (!callback(section)) { + return; + } + } +} + void DiscreteSlider::mousePressEvent(QMouseEvent *e) { auto index = getIndexFromPosition(e->pos()); if (_selectOnPress) { @@ -183,20 +192,55 @@ void SettingsSlider::resizeSections(int newWidth) { auto count = getSectionsCount(); if (!count) return; - auto sectionsWidth = newWidth - (count - 1) * _st.barSkip; - auto sectionWidth = sectionsWidth / float64(count); + auto sectionWidths = countSectionsWidths(newWidth); + auto skip = 0; auto x = 0.; - enumerateSections([this, &x, &skip, sectionWidth](Section §ion) { + auto sectionWidth = sectionWidths.begin(); + enumerateSections([&](Section §ion) { + Expects(sectionWidth != sectionWidths.end()); + section.left = qFloor(x) + skip; - x += sectionWidth; + x += *sectionWidth; section.width = qRound(x) - (section.left - skip); skip += _st.barSkip; + ++sectionWidth; return true; }); stopAnimation(); } +std::vector SettingsSlider::countSectionsWidths( + int newWidth) const { + auto count = getSectionsCount(); + auto sectionsWidth = newWidth - (count - 1) * _st.barSkip; + auto sectionWidth = sectionsWidth / float64(count); + + auto result = std::vector(count, sectionWidth); + auto labelsWidth = 0; + auto commonWidth = true; + enumerateSections([&](const Section §ion) { + labelsWidth += section.labelWidth; + if (section.labelWidth >= sectionWidth) { + commonWidth = false; + } + return true; + }); + // If labelsWidth > sectionsWidth we're screwed anyway. + if (!commonWidth && labelsWidth <= sectionsWidth) { + auto padding = (sectionsWidth - labelsWidth) / (2. * count); + auto currentWidth = result.begin(); + enumerateSections([&](const Section §ion) { + Expects(currentWidth != result.end()); + + *currentWidth = padding + section.labelWidth + padding; + ++currentWidth; + return true; + }); + } + return result; +} + int SettingsSlider::resizeGetHeight(int newWidth) { resizeSections(newWidth); return _st.height; diff --git a/Telegram/SourceFiles/ui/widgets/discrete_sliders.h b/Telegram/SourceFiles/ui/widgets/discrete_sliders.h index 8f1489193..0edad25f0 100644 --- a/Telegram/SourceFiles/ui/widgets/discrete_sliders.h +++ b/Telegram/SourceFiles/ui/widgets/discrete_sliders.h @@ -71,6 +71,9 @@ protected: template void enumerateSections(Lambda callback); + template + void enumerateSections(Lambda callback) const; + virtual void startRipple(int sectionIndex) { } @@ -122,6 +125,7 @@ private: QImage prepareRippleMask(int sectionIndex, const Section §ion); void resizeSections(int newWidth); + std::vector countSectionsWidths(int newWidth) const; const style::SettingsSlider &_st; int _rippleTopRoundRadius = 0;