@@ -114,6 +114,8 @@ is_empty_document_body (tree body) {
114114
115115// / 左侧边栏最小宽度(像素)。
116116constexpr int kSidebarMinWidth = 200 ;
117+ // / 左侧边栏收起后的窄条宽度(像素)。
118+ constexpr int kSidebarCollapsedWidth = 48 ;
117119// / 边栏布局水平边距。
118120constexpr int kSidebarMarginX = 12 ;
119121// / 边栏布局垂直边距。
@@ -201,9 +203,12 @@ QTChatTabWidget::QTChatTabWidget (QWidget* parent)
201203 : QWidget (parent), sidebarWidget_ (nullptr ), contentWidget_ (nullptr ),
202204 conversationCountLabel_ (nullptr ), conversationListWidget_ (nullptr ),
203205 conversationListLayout_ (nullptr ), newChatButton_ (nullptr ),
204- conversationStack_ (nullptr ), activeConversation_ (nullptr ),
205- nextConversationTitleId_ (1 ), chatMenuToolBar_ (nullptr ),
206- chatModeToolBar_ (nullptr ), chatFocusToolBar_ (nullptr ) {
206+ collapseButton_ (nullptr ), sidebarNormalContent_ (nullptr ),
207+ sidebarCollapsedBar_ (nullptr ), conversationStack_ (nullptr ),
208+ activeConversation_ (nullptr ), nextConversationTitleId_ (1 ),
209+ sidebarCollapsed_ (false ), sidebarExpandedWidth_ (0 ),
210+ chatMenuToolBar_ (nullptr ), chatModeToolBar_ (nullptr ),
211+ chatFocusToolBar_ (nullptr ) {
207212 setFocusPolicy (Qt::StrongFocus);
208213
209214 QHBoxLayout* mainLayout= new QHBoxLayout (this );
@@ -227,8 +232,9 @@ QTChatTabWidget::QTChatTabWidget (QWidget* parent)
227232 setup_left_sidebar (sidebarLayout);
228233 sidebar->adjustSize ();
229234 const int contentWidth= sidebar->sizeHint ().width ();
230- sidebar->setFixedWidth (
231- qMax (DpiUtils::scaled (kSidebarMinWidth ), contentWidth));
235+ sidebarExpandedWidth_=
236+ qMax (DpiUtils::scaled (kSidebarMinWidth ), contentWidth);
237+ sidebar->setFixedWidth (sidebarExpandedWidth_);
232238 mainLayout->addWidget (sidebar);
233239
234240 // 右侧内容区
@@ -251,34 +257,21 @@ QTChatTabWidget::~QTChatTabWidget () {
251257 */
252258void
253259QTChatTabWidget::setup_left_sidebar (QVBoxLayout* sidebarLayout) {
254- // 顶部行:标题 + 收缩按钮
255- QHBoxLayout* headerLayout= new QHBoxLayout ();
256- headerLayout->setSpacing (0 );
257-
258- QLabel* navTitle= new QLabel (" Chat" , this );
260+ // ---- 展开态:正常内容容器 ----
261+ QWidget* normalContent= new QWidget (sidebarWidget_);
262+ normalContent->setObjectName (" chat-tab-sidebar-normal" );
263+ QVBoxLayout* normalLayout= new QVBoxLayout (normalContent);
264+ normalLayout->setContentsMargins (0 , 0 , 0 , 0 );
265+ normalLayout->setSpacing (DpiUtils::scaled (kSidebarSpacing ));
266+
267+ // 顶部标题
268+ QLabel* navTitle= new QLabel (" Chat" , normalContent);
259269 navTitle->setObjectName (" chat-tab-nav-title" );
260270 DpiUtils::applyScaledFont (navTitle, kNavTitleFontPx );
261- headerLayout->addWidget (navTitle);
262-
263- headerLayout->addStretch ();
264-
265- QPushButton* collapseBtn= new QPushButton (" 收缩" , this );
266- collapseBtn->setObjectName (" chat-tab-collapse-btn" );
267- collapseBtn->setFocusPolicy (Qt::NoFocus);
268- collapseBtn->setCursor (Qt::PointingHandCursor);
269- DpiUtils::applyScaledFont (collapseBtn, kCollapseFontPx );
270- collapseBtn->setStyleSheet (
271- QString (" QPushButton { border: 1px solid #cccccc; border-radius: %1px; "
272- " padding: %2px %3px; background-color: #ffffff; }" )
273- .arg (DpiUtils::scaled (kCollapseBorderRadius ))
274- .arg (DpiUtils::scaled (kCollapsePadY ))
275- .arg (DpiUtils::scaled (kCollapsePadX )));
276- headerLayout->addWidget (collapseBtn);
277-
278- sidebarLayout->addLayout (headerLayout);
271+ normalLayout->addWidget (navTitle);
279272
280273 // New chat 按钮
281- newChatButton_= new QPushButton (" New chat" , this );
274+ newChatButton_= new QPushButton (" New chat" , normalContent );
282275 newChatButton_->setObjectName (" chat-tab-new-btn" );
283276 newChatButton_->setFocusPolicy (Qt::NoFocus);
284277 newChatButton_->setCursor (Qt::PointingHandCursor);
@@ -288,22 +281,71 @@ QTChatTabWidget::setup_left_sidebar (QVBoxLayout* sidebarLayout) {
288281 .arg (DpiUtils::scaled (kNavButtonPadX )));
289282 connect (newChatButton_, &QPushButton::clicked, this ,
290283 [this ] () { create_new_conversation (); });
291- sidebarLayout ->addWidget (newChatButton_);
284+ normalLayout ->addWidget (newChatButton_);
292285
293- conversationCountLabel_= new QLabel (" Conversations (0)" , this );
286+ conversationCountLabel_= new QLabel (" Conversations (0)" , normalContent );
294287 conversationCountLabel_->setObjectName (" chat-tab-conversation-count" );
295288 DpiUtils::applyScaledFont (conversationCountLabel_, kNavTitleFontPx );
296289 conversationCountLabel_->setStyleSheet (" color: #666666;" );
297- sidebarLayout ->addWidget (conversationCountLabel_);
290+ normalLayout ->addWidget (conversationCountLabel_);
298291
299- conversationListWidget_= new QWidget (this );
292+ conversationListWidget_= new QWidget (normalContent );
300293 conversationListWidget_->setObjectName (" chat-tab-conversation-list" );
301294 conversationListLayout_= new QVBoxLayout (conversationListWidget_);
302295 conversationListLayout_->setContentsMargins (0 , 0 , 0 , 0 );
303296 conversationListLayout_->setSpacing (DpiUtils::scaled (kSidebarSpacing ));
304- sidebarLayout->addWidget (conversationListWidget_);
297+ normalLayout->addWidget (conversationListWidget_);
298+
299+ normalLayout->addStretch ();
305300
306- sidebarLayout->addStretch ();
301+ // 底部收缩按钮
302+ QPushButton* collapseBtn= new QPushButton (" 收缩" , normalContent);
303+ collapseBtn->setObjectName (" chat-tab-collapse-btn" );
304+ collapseBtn->setFocusPolicy (Qt::NoFocus);
305+ collapseBtn->setCursor (Qt::PointingHandCursor);
306+ DpiUtils::applyScaledFont (collapseBtn, kCollapseFontPx );
307+ collapseBtn->setStyleSheet (
308+ QString (" QPushButton { border: 1px solid #cccccc; border-radius: %1px; "
309+ " padding: %2px %3px; background-color: #ffffff; }" )
310+ .arg (DpiUtils::scaled (kCollapseBorderRadius ))
311+ .arg (DpiUtils::scaled (kCollapsePadY ))
312+ .arg (DpiUtils::scaled (kCollapsePadX )));
313+ connect (collapseBtn, &QPushButton::clicked, this ,
314+ [this ] () { toggle_sidebar (); });
315+ collapseButton_= collapseBtn;
316+ normalLayout->addWidget (collapseBtn);
317+
318+ sidebarNormalContent_= normalContent;
319+ sidebarLayout->addWidget (normalContent);
320+
321+ // ---- 收起态:窄条容器,底部展开按钮 ----
322+ QWidget* collapsedBar= new QWidget (sidebarWidget_);
323+ collapsedBar->setObjectName (" chat-tab-sidebar-collapsed" );
324+ QVBoxLayout* collapsedLayout= new QVBoxLayout (collapsedBar);
325+ collapsedLayout->setContentsMargins (0 , 0 , 0 ,
326+ DpiUtils::scaled (kSidebarMarginY ));
327+ collapsedLayout->setSpacing (0 );
328+
329+ collapsedLayout->addStretch ();
330+
331+ QPushButton* expandBtn= new QPushButton (" <" , collapsedBar);
332+ expandBtn->setObjectName (" chat-tab-collapsed-expand-btn" );
333+ expandBtn->setFocusPolicy (Qt::NoFocus);
334+ expandBtn->setCursor (Qt::PointingHandCursor);
335+ DpiUtils::applyScaledFont (expandBtn, kCollapseFontPx );
336+ expandBtn->setStyleSheet (
337+ QString (" QPushButton { border: none; border-radius: %1px; "
338+ " padding: %2px 0px; background-color: transparent; } "
339+ " QPushButton:hover { background-color: #e0e0e0; }" )
340+ .arg (DpiUtils::scaled (kCollapseBorderRadius ))
341+ .arg (DpiUtils::scaled (kCollapsePadY )));
342+ connect (expandBtn, &QPushButton::clicked, this ,
343+ [this ] () { toggle_sidebar (); });
344+ collapsedLayout->addWidget (expandBtn);
345+
346+ collapsedBar->hide ();
347+ sidebarCollapsedBar_= collapsedBar;
348+ sidebarLayout->addWidget (collapsedBar);
307349}
308350
309351/* *
@@ -515,6 +557,31 @@ QTChatTabWidget::refresh_sidebar () {
515557 }
516558}
517559
560+ /* *
561+ * @brief 切换侧边栏的收起/展开状态。
562+ *
563+ * 收起时 sidebar 缩为窄条(仅含展开按钮),展开时恢复完整内容。
564+ */
565+ void
566+ QTChatTabWidget::toggle_sidebar () {
567+ if (!sidebarWidget_) return ;
568+
569+ if (sidebarCollapsed_) {
570+ // 展开:显示正常内容,隐藏窄条,恢复宽度
571+ if (sidebarNormalContent_) sidebarNormalContent_->show ();
572+ if (sidebarCollapsedBar_) sidebarCollapsedBar_->hide ();
573+ sidebarWidget_->setFixedWidth (sidebarExpandedWidth_);
574+ sidebarCollapsed_= false ;
575+ }
576+ else {
577+ // 收起:隐藏正常内容,显示窄条,缩为窄条
578+ if (sidebarNormalContent_) sidebarNormalContent_->hide ();
579+ if (sidebarCollapsedBar_) sidebarCollapsedBar_->show ();
580+ sidebarWidget_->setFixedWidth (DpiUtils::scaled (kSidebarCollapsedWidth ));
581+ sidebarCollapsed_= true ;
582+ }
583+ }
584+
518585/* *
519586 * @brief 将指定面板从欢迎态切换到会话态。
520587 *
0 commit comments