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,13 @@ 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 = std::max (
155+ 1 .0f , m_cardsScroll != nullptr ? m_cardsScroll->contentViewportWidth () : contentWidth
156+ );
128157 const float cardInnerWidth = std::max (1 .0f , cardWidth - Style::spaceMd * scale * 2 .0f );
129158 const float headerTextMaxWidth =
130159 std::max (1 .0f , cardInnerWidth - Style::fontSizeTitle * scale - Style::spaceSm * scale);
@@ -142,7 +171,6 @@ void MonitorTab::doLayout(Renderer& renderer, float contentWidth, float bodyHeig
142171 }
143172 }
144173
145- m_rootLayout->setSize (contentWidth, bodyHeight);
146174 m_rootLayout->layout (renderer);
147175}
148176
@@ -210,7 +238,7 @@ void MonitorTab::doUpdate(Renderer& renderer) {
210238}
211239
212240void MonitorTab::rebuildCards (Renderer& /* renderer*/ ) {
213- if (m_brightness == nullptr || m_rootLayout == nullptr ) {
241+ if (m_brightness == nullptr || m_cardsLayout == nullptr ) {
214242 return ;
215243 }
216244
@@ -224,7 +252,7 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
224252 // Remove old cards
225253 for (auto & card : m_cards) {
226254 if (card.card != nullptr ) {
227- m_rootLayout ->removeChild (card.card );
255+ m_cardsLayout ->removeChild (card.card );
228256 }
229257 }
230258 m_cards.clear ();
@@ -234,6 +262,9 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
234262 if (m_emptyState != nullptr ) {
235263 m_emptyState->setVisible (empty);
236264 }
265+ if (m_cardsScroll != nullptr ) {
266+ m_cardsScroll->setVisible (!empty);
267+ }
237268
238269 if (empty) {
239270 return ;
@@ -351,7 +382,7 @@ void MonitorTab::rebuildCards(Renderer& /*renderer*/) {
351382 card->addChild (std::move (sliderRow));
352383
353384 auto * cardPtr = card.get ();
354- m_rootLayout ->addChild (std::move (card));
385+ m_cardsLayout ->addChild (std::move (card));
355386
356387 m_cards.push_back (
357388 DisplayCard{
0 commit comments