55#include " render/core/renderer.h"
66#include " system/brightness_service.h"
77#include " ui/builders.h"
8+ #include " ui/controls/scroll_view.h"
89#include " ui/palette.h"
910
1011#include < algorithm>
@@ -76,9 +77,30 @@ std::unique_ptr<Flex> MonitorTab::create() {
7677 .gap = Style::spaceMd * scale,
7778 });
7879
80+ auto cardsScroll = ui::scrollView ({
81+ .out = &m_cardsScroll,
82+ .scrollbarVisible = true ,
83+ .viewportPaddingH = 0 .0f ,
84+ .viewportPaddingV = 0 .0f ,
85+ .flexGrow = 1 .0f ,
86+ .configure = [](ScrollView& scrollView) {
87+ scrollView.clearFill ();
88+ scrollView.clearBorder ();
89+ },
90+ });
91+ m_cardsLayout = cardsScroll->content ();
92+ m_cardsLayout->setDirection (FlexDirection::Vertical);
93+ m_cardsLayout->setAlign (FlexAlign::Stretch);
94+ m_cardsLayout->setGap (Style::spaceMd * scale);
95+ tab->addChild (std::move (cardsScroll));
96+
7997 // Empty state (shown when no displays are known)
8098 auto emptyState = ui::column (
81- {.out = &m_emptyState, .align = FlexAlign::Center, .justify = FlexJustify::Center, .flexGrow = 1 .0f },
99+ {.out = &m_emptyState,
100+ .align = FlexAlign::Center,
101+ .justify = FlexJustify::Center,
102+ .flexGrow = 1 .0f ,
103+ .visible = false },
82104 ui::label ({
83105 .text = i18n::tr (" control-center.display.no-displays" ),
84106 .fontSize = Style::fontSizeBody * scale,
@@ -103,6 +125,8 @@ void MonitorTab::onClose() {
103125 m_debounceTimer.stop ();
104126 m_rootLayout = nullptr ;
105127 m_emptyState = nullptr ;
128+ m_cardsScroll = nullptr ;
129+ m_cardsLayout = nullptr ;
106130 m_cards.clear ();
107131 m_lastDisplayListKey.clear ();
108132}
@@ -123,8 +147,12 @@ void MonitorTab::doLayout(Renderer& renderer, float contentWidth, float bodyHeig
123147
124148 rebuildCards (renderer);
125149
150+ m_rootLayout->setSize (contentWidth, bodyHeight);
151+ m_rootLayout->layout (renderer);
152+
126153 const float scale = contentScale ();
127- const float cardWidth = std::max (1 .0f , contentWidth);
154+ const float cardWidth =
155+ std::max (1 .0f , m_cardsScroll != nullptr ? m_cardsScroll->contentViewportWidth () : contentWidth);
128156 const float cardInnerWidth = std::max (1 .0f , cardWidth - Style::spaceMd * scale * 2 .0f );
129157 const float headerTextMaxWidth =
130158 std::max (1 .0f , cardInnerWidth - Style::fontSizeTitle * scale - Style::spaceSm * scale);
@@ -142,7 +170,6 @@ void MonitorTab::doLayout(Renderer& renderer, float contentWidth, float bodyHeig
142170 }
143171 }
144172
145- m_rootLayout->setSize (contentWidth, bodyHeight);
146173 m_rootLayout->layout (renderer);
147174}
148175
@@ -210,7 +237,7 @@ void MonitorTab::doUpdate(Renderer& renderer) {
210237}
211238
212239void MonitorTab::rebuildCards (Renderer& /* renderer*/ ) {
213- if (m_brightness == nullptr || m_rootLayout == nullptr ) {
240+ if (m_brightness == nullptr || m_cardsLayout == nullptr ) {
214241 return ;
215242 }
216243
@@ -224,7 +251,7 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
224251 // Remove old cards
225252 for (auto & card : m_cards) {
226253 if (card.card != nullptr ) {
227- m_rootLayout ->removeChild (card.card );
254+ m_cardsLayout ->removeChild (card.card );
228255 }
229256 }
230257 m_cards.clear ();
@@ -234,6 +261,9 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
234261 if (m_emptyState != nullptr ) {
235262 m_emptyState->setVisible (empty);
236263 }
264+ if (m_cardsScroll != nullptr ) {
265+ m_cardsScroll->setVisible (!empty);
266+ }
237267
238268 if (empty) {
239269 return ;
@@ -351,7 +381,7 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
351381 card->addChild (std::move (sliderRow));
352382
353383 auto * cardPtr = card.get ();
354- m_rootLayout ->addChild (std::move (card));
384+ m_cardsLayout ->addChild (std::move (card));
355385
356386 m_cards.push_back (
357387 DisplayCard{
0 commit comments