11from datetime import datetime
22
3- from PyQt6 .QtWidgets import QAbstractItemView , QFrame , QVBoxLayout , QScrollArea
3+ from PyQt6 .QtWidgets import (
4+ QFrame ,
5+ QHBoxLayout ,
6+ QScrollArea ,
7+ QVBoxLayout ,
8+ )
9+
10+ from feeluown .gui .widgets .textbtn import TextButton
411
512from feeluown .library import SearchType
613from feeluown .utils .aio import run_afn
2229from feeluown .i18n import t
2330
2431
32+ def _toggle_rows (checked , default_count , table , btn ):
33+ table .set_fixed_row_count (default_count if checked else - 1 )
34+ btn .setText (t ("show-more" ) if checked else t ("show-less" ))
35+
36+
37+ _ACTIVE_TABLE_ATTR = {
38+ "songs" : "songs_table" ,
39+ "albums" : "albums_table" ,
40+ "artists" : "artists_table" ,
41+ "playlists" : "playlists_table" ,
42+ "videos" : "videos_table" ,
43+ }
44+
45+
2546Tabs = [
2647 (t ("track" ), SearchType .so ),
2748 (t ("album" ), SearchType .al ),
@@ -111,7 +132,6 @@ async def search_and_render(self, q, search_type, source_in):
111132 tab_index = get_tab_idx (search_type )
112133 succeed = 0
113134 start = datetime .now ()
114- is_first = True # Is first search result.
115135 if source_in is not None :
116136 source_count = len (source_in )
117137 else :
@@ -135,21 +155,27 @@ async def search_and_render(self, q, search_type, source_in):
135155 table_container = TableContainer (app , view .accordion )
136156 table_container .layout ().setContentsMargins (0 , 0 , 0 , 0 )
137157
138- # HACK: set fixed row for tables.
139- # pylint: disable=protected-access
140- for table in table_container ._tables :
141- assert isinstance (table , QAbstractItemView )
142- delegate = table .itemDelegate ()
143- if isinstance (delegate , ImgCardListDelegate ):
144- table .set_fixed_row_count (2 )
145- delegate .update_settings ("card_min_width" , 140 )
146- elif isinstance (table , SongsTableView ):
147- table .set_fixed_row_count (8 )
148- table .set_row_height (table .verticalHeader ().defaultSectionSize ())
149-
150158 renderer = SearchResultRenderer (q , tab_index , source_in = source_in )
151159 await table_container .set_renderer (renderer )
152160 _ , search_type , attrname , show_handler = renderer .tabs [tab_index ]
161+
162+ # Find the active table and set its fixed row count.
163+ active_table = getattr (
164+ table_container , _ACTIVE_TABLE_ATTR [attrname ]
165+ )
166+ if isinstance (active_table , SongsTableView ):
167+ default_count = 8
168+ active_table .set_fixed_row_count (default_count )
169+ active_table .set_row_height (
170+ active_table .verticalHeader ().defaultSectionSize ()
171+ )
172+ else :
173+ default_count = 2
174+ delegate = active_table .itemDelegate ()
175+ if isinstance (delegate , ImgCardListDelegate ):
176+ active_table .set_fixed_row_count (default_count )
177+ delegate .update_settings ("card_min_width" , 140 )
178+
153179 objects = getattr (result , attrname ) or []
154180 if not objects : # Result is empty.
155181 hint_msgs .append (
@@ -168,12 +194,35 @@ async def search_and_render(self, q, search_type, source_in):
168194 source = objects [0 ].source
169195 provider = app .library .get (source )
170196 provider_name = provider .name
171- if is_first is False :
172- table_container .hide ()
173- view .accordion .add_section (MidHeader (provider_name ), table_container , 6 , 12 )
197+
198+ header_label = MidHeader (provider_name )
199+
200+ expand_btn = TextButton (t ("show-more" ))
201+ expand_btn .setCheckable (True )
202+ expand_btn .setChecked (True )
203+ expand_btn .toggled .connect (
204+ lambda checked , tbl = active_table , count = default_count ,
205+ btn = expand_btn : _toggle_rows (checked , count , tbl , btn )
206+ )
207+
208+ content_widget = QFrame ()
209+ content_layout = QVBoxLayout (content_widget )
210+ content_layout .setContentsMargins (0 , 0 , 0 , 0 )
211+ content_layout .setSpacing (0 )
212+ content_layout .addWidget (table_container )
213+
214+ footer = QFrame ()
215+ footer_layout = QHBoxLayout (footer )
216+ footer_layout .setContentsMargins (0 , 0 , 0 , 0 )
217+ footer_layout .addStretch ()
218+ footer_layout .addWidget (expand_btn )
219+ content_layout .addWidget (footer )
220+
221+ view .accordion .add_section (
222+ header_label , content_widget , 6 , 12
223+ )
174224 renderer .meta_widget .hide ()
175225 renderer .toolbar .hide ()
176- is_first = False
177226 time_cost = (datetime .now () - start ).total_seconds ()
178227 hint_msgs .pop (0 )
179228 hint_msgs .insert (
0 commit comments