@@ -75,18 +75,38 @@ class NextStepsPanel(QDialog):
7575
7676 dont_show_again_changed = Signal (bool )
7777
78+ # Styling constants
79+ MIN_WIDTH = 450
80+ MAX_WIDTH = 600
81+ MIN_HEIGHT = 360
82+ FRAME_PADDING = 8
83+ FRAME_BORDER_RADIUS = 4
84+ LAYOUT_MARGIN = 12
85+ LAYOUT_SPACING = 10
86+
87+ # Card background colors
88+ COLOR_BENCHMARK = "rgba(255, 193, 7, 0.08)"
89+ COLOR_PYPESTO = "rgba(100, 149, 237, 0.08)"
90+ COLOR_COPASI = "rgba(169, 169, 169, 0.08)"
91+ COLOR_OTHER_TOOLS = "rgba(144, 238, 144, 0.08)"
92+
7893 def __init__ (self , parent = None ):
7994 super ().__init__ (parent )
8095 self .setWindowTitle ("Possible next steps" )
8196 self .setModal (False )
82- self .setMinimumWidth (450 )
83- self .setMaximumWidth (600 )
84- self .setMinimumHeight (360 )
97+ self .setMinimumWidth (self . MIN_WIDTH )
98+ self .setMaximumWidth (self . MAX_WIDTH )
99+ self .setMinimumHeight (self . MIN_HEIGHT )
85100
86101 # Main layout
87102 main_layout = QVBoxLayout (self )
88- main_layout .setContentsMargins (12 , 12 , 12 , 12 )
89- main_layout .setSpacing (10 )
103+ main_layout .setContentsMargins (
104+ self .LAYOUT_MARGIN ,
105+ self .LAYOUT_MARGIN ,
106+ self .LAYOUT_MARGIN ,
107+ self .LAYOUT_MARGIN ,
108+ )
109+ main_layout .setSpacing (self .LAYOUT_SPACING )
90110
91111 # Description
92112 desc = QLabel (
@@ -100,88 +120,44 @@ def __init__(self, parent=None):
100120 suggestions_layout .setSpacing (8 )
101121
102122 # Benchmark Collection action
103- benchmark_frame = QFrame ()
104- benchmark_frame .setStyleSheet (
105- "QFrame { background-color: rgba(255, 193, 7, 0.08); "
106- "border-radius: 4px; padding: 8px; }"
107- )
108- benchmark_layout = QVBoxLayout (benchmark_frame )
109- benchmark_layout .setContentsMargins (8 , 8 , 8 , 8 )
110- benchmark_layout .setSpacing (4 )
111-
112- benchmark_text = QTextBrowser ()
113- benchmark_text .setOpenExternalLinks (True )
114- benchmark_text .setFrameStyle (QFrame .NoFrame )
115- benchmark_text .setStyleSheet (
116- "QTextBrowser { background: transparent; }"
123+ benchmark_frame = self ._create_tool_card (
124+ bg_color = self .COLOR_BENCHMARK ,
125+ html_content = (
126+ '<p style="margin:0; line-height:1.3;">'
127+ "<b>📚 Contribute to Benchmark Collection</b><br/>"
128+ "Share your PEtab problem with the community to validate it, "
129+ "enable reproducibility, and support benchmarking<br/>"
130+ '<a href="https://github.com/Benchmarking-Initiative/'
131+ 'Benchmark-Models-PEtab">Benchmark Collection</a></p>'
132+ ),
117133 )
118- benchmark_text .setVerticalScrollBarPolicy (
119- Qt .ScrollBarPolicy .ScrollBarAlwaysOff
120- )
121- benchmark_text .setHtml (
122- '<p style="margin:0; line-height:1.3;">'
123- "<b>📚 Contribute to Benchmark Collection</b><br/>"
124- "Share your PEtab problem with the community to validate it, "
125- "enable reproducibility, and support benchmarking<br/>"
126- '<a href="https://github.com/Benchmarking-Initiative/'
127- 'Benchmark-Models-PEtab">Benchmark Collection</a></p>'
128- )
129- benchmark_layout .addWidget (benchmark_text )
130134 suggestions_layout .addWidget (benchmark_frame )
131135
132136 # pyPESTO action
133- pypesto_frame = QFrame ()
134- pypesto_frame .setStyleSheet (
135- "QFrame { background-color: rgba(100, 149, 237, 0.08); "
136- "border-radius: 4px; padding: 8px; }"
137- )
138- pypesto_layout = QVBoxLayout (pypesto_frame )
139- pypesto_layout .setContentsMargins (8 , 8 , 8 , 8 )
140- pypesto_layout .setSpacing (4 )
141-
142- pypesto_text = QTextBrowser ()
143- pypesto_text .setOpenExternalLinks (True )
144- pypesto_text .setFrameStyle (QFrame .NoFrame )
145- pypesto_text .setStyleSheet ("QTextBrowser { background: transparent; }" )
146- pypesto_text .setVerticalScrollBarPolicy (
147- Qt .ScrollBarPolicy .ScrollBarAlwaysOff
137+ pypesto_frame = self ._create_tool_card (
138+ bg_color = self .COLOR_PYPESTO ,
139+ html_content = (
140+ '<p style="margin:0; line-height:1.3;">'
141+ "<b>▶ Parameter Estimation with pyPESTO</b><br/>"
142+ "Use pyPESTO for parameter estimation, uncertainty analysis, "
143+ "and model selection<br/>"
144+ '<a href="https://pypesto.readthedocs.io/en/latest/example/'
145+ 'petab_import.html">pyPESTO documentation</a></p>'
146+ ),
148147 )
149- pypesto_text .setHtml (
150- '<p style="margin:0; line-height:1.3;">'
151- "<b>▶ Parameter Estimation with pyPESTO</b><br/>"
152- "Use pyPESTO for parameter estimation, uncertainty analysis, "
153- "and model selection<br/>"
154- '<a href="https://pypesto.readthedocs.io/en/latest/example/'
155- 'petab_import.html">pyPESTO documentation</a></p>'
156- )
157- pypesto_layout .addWidget (pypesto_text )
158148 suggestions_layout .addWidget (pypesto_frame )
159149
160150 # COPASI action
161- copasi_frame = QFrame ()
162- copasi_frame .setStyleSheet (
163- "QFrame { background-color: rgba(169, 169, 169, 0.08); "
164- "border-radius: 4px; padding: 8px; }"
165- )
166- copasi_layout = QVBoxLayout (copasi_frame )
167- copasi_layout .setContentsMargins (8 , 8 , 8 , 8 )
168- copasi_layout .setSpacing (4 )
169-
170- copasi_text = QTextBrowser ()
171- copasi_text .setOpenExternalLinks (True )
172- copasi_text .setFrameStyle (QFrame .NoFrame )
173- copasi_text .setStyleSheet ("QTextBrowser { background: transparent; }" )
174- copasi_text .setVerticalScrollBarPolicy (
175- Qt .ScrollBarPolicy .ScrollBarAlwaysOff
151+ copasi_frame = self ._create_tool_card (
152+ bg_color = self .COLOR_COPASI ,
153+ html_content = (
154+ '<p style="margin:0; line-height:1.3;">'
155+ "<b>⚙ Advanced Model Adaptation and Simulation</b><br/>"
156+ "Use COPASI for further model adjustment and advanced "
157+ "simulation with a graphical interface<br/>"
158+ '<a href="https://copasi.org">COPASI website</a></p>'
159+ ),
176160 )
177- copasi_text .setHtml (
178- '<p style="margin:0; line-height:1.3;">'
179- "<b>⚙ Advanced Model Adaptation and Simulation</b><br/>"
180- "Use COPASI for further model adjustment and advanced "
181- "simulation with a graphical interface<br/>"
182- '<a href="https://copasi.org">COPASI website</a></p>'
183- )
184- copasi_layout .addWidget (copasi_text )
185161 suggestions_layout .addWidget (copasi_frame )
186162
187163 main_layout .addLayout (suggestions_layout )
@@ -203,12 +179,18 @@ def __init__(self, parent=None):
203179 # Other tools frame (initially hidden)
204180 self ._other_tools_frame = QFrame ()
205181 self ._other_tools_frame .setStyleSheet (
206- "QFrame { background-color: rgba(144, 238, 144, 0.08); "
207- "border-radius: 4px; padding: 8px; }"
182+ f"QFrame {{ background-color: { self .COLOR_OTHER_TOOLS } ; "
183+ f"border-radius: { self .FRAME_BORDER_RADIUS } px; "
184+ f"padding: { self .FRAME_PADDING } px; }}"
208185 )
209186 self ._other_tools_frame .setVisible (False )
210187 other_tools_layout = QVBoxLayout (self ._other_tools_frame )
211- other_tools_layout .setContentsMargins (8 , 8 , 8 , 8 )
188+ other_tools_layout .setContentsMargins (
189+ self .FRAME_PADDING ,
190+ self .FRAME_PADDING ,
191+ self .FRAME_PADDING ,
192+ self .FRAME_PADDING ,
193+ )
212194 other_tools_layout .setSpacing (4 )
213195
214196 # Framing text
@@ -282,6 +264,46 @@ def __init__(self, parent=None):
282264
283265 main_layout .addLayout (bottom_layout )
284266
267+ def _create_tool_card (
268+ self , bg_color : str , html_content : str , scrollbar_policy = None
269+ ) -> QFrame :
270+ """Create a styled card for displaying tool information.
271+
272+ Args:
273+ bg_color: Background color for the frame (rgba string)
274+ html_content: HTML content to display in the text browser
275+ scrollbar_policy: Optional scrollbar policy (defaults to AlwaysOff)
276+
277+ Returns:
278+ Configured QFrame containing the tool information
279+ """
280+ frame = QFrame ()
281+ frame .setStyleSheet (
282+ f"QFrame {{ background-color: { bg_color } ; "
283+ f"border-radius: { self .FRAME_BORDER_RADIUS } px; "
284+ f"padding: { self .FRAME_PADDING } px; }}"
285+ )
286+ layout = QVBoxLayout (frame )
287+ layout .setContentsMargins (
288+ self .FRAME_PADDING ,
289+ self .FRAME_PADDING ,
290+ self .FRAME_PADDING ,
291+ self .FRAME_PADDING ,
292+ )
293+ layout .setSpacing (4 )
294+
295+ text_browser = QTextBrowser ()
296+ text_browser .setOpenExternalLinks (True )
297+ text_browser .setFrameStyle (QFrame .NoFrame )
298+ text_browser .setStyleSheet ("QTextBrowser { background: transparent; }" )
299+ if scrollbar_policy is None :
300+ scrollbar_policy = Qt .ScrollBarPolicy .ScrollBarAlwaysOff
301+ text_browser .setVerticalScrollBarPolicy (scrollbar_policy )
302+ text_browser .setHtml (html_content )
303+ layout .addWidget (text_browser )
304+
305+ return frame
306+
285307 def _toggle_other_tools (self , checked ):
286308 """Toggle visibility of other tools section."""
287309 self ._other_tools_frame .setVisible (checked )
0 commit comments