ctkCollapsibleButton.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QApplication>
  16. #include <QCleanlooksStyle>
  17. #include <QDebug>
  18. #include <QLayout>
  19. #include <QMouseEvent>
  20. #include <QPainter>
  21. #include <QPushButton>
  22. #include <QStyle>
  23. #include <QStyleOptionButton>
  24. #include <QStyleOptionFrameV3>
  25. // CTK includes
  26. #include "ctkCollapsibleButton.h"
  27. //-----------------------------------------------------------------------------
  28. class ctkCollapsibleButtonPrivate
  29. {
  30. Q_DECLARE_PUBLIC(ctkCollapsibleButton);
  31. protected:
  32. ctkCollapsibleButton* const q_ptr;
  33. public:
  34. ctkCollapsibleButtonPrivate(ctkCollapsibleButton& object);
  35. void init();
  36. bool Collapsed;
  37. // Contents frame
  38. QFrame::Shape ContentsFrameShape;
  39. QFrame::Shadow ContentsFrameShadow;
  40. int ContentsLineWidth;
  41. int ContentsMidLineWidth;
  42. int CollapsedHeight;
  43. bool ExclusiveMouseOver;
  44. bool LookOffWhenChecked;
  45. int MaximumHeight; // use carefully
  46. // Tuning of the button look&feel
  47. Qt::Alignment TextAlignment;
  48. Qt::Alignment IndicatorAlignment;
  49. };
  50. //-----------------------------------------------------------------------------
  51. ctkCollapsibleButtonPrivate::ctkCollapsibleButtonPrivate(ctkCollapsibleButton& object)
  52. :q_ptr(&object)
  53. {
  54. }
  55. //-----------------------------------------------------------------------------
  56. void ctkCollapsibleButtonPrivate::init()
  57. {
  58. Q_Q(ctkCollapsibleButton);
  59. q->setCheckable(true);
  60. // checked and Collapsed are synchronized: checked != Collapsed
  61. q->setChecked(true);
  62. this->Collapsed = false;
  63. this->ContentsFrameShape = QFrame::NoFrame;
  64. this->ContentsFrameShadow = QFrame::Plain;
  65. this->ContentsLineWidth = 1;
  66. this->ContentsMidLineWidth = 0;
  67. this->CollapsedHeight = 10;
  68. this->ExclusiveMouseOver = false;
  69. this->LookOffWhenChecked = true; // set as a prop ?
  70. this->MaximumHeight = q->maximumHeight();
  71. this->TextAlignment = Qt::AlignLeft | Qt::AlignVCenter;
  72. this->IndicatorAlignment = Qt::AlignLeft | Qt::AlignVCenter;
  73. q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum,
  74. QSizePolicy::Preferred,
  75. QSizePolicy::DefaultType));
  76. q->setContentsMargins(0, q->buttonSizeHint().height(),0 , 0);
  77. // by default QAbstractButton changed the background role to Button
  78. // we want a regular background
  79. q->setBackgroundRole(QPalette::Window);
  80. QObject::connect(q, SIGNAL(toggled(bool)),
  81. q, SLOT(onToggled(bool)));
  82. }
  83. //-----------------------------------------------------------------------------
  84. void ctkCollapsibleButton::initStyleOption(QStyleOptionButton* option)const
  85. {
  86. Q_D(const ctkCollapsibleButton);
  87. if (option == 0)
  88. {
  89. return;
  90. }
  91. option->initFrom(this);
  92. if (this->isDown() )
  93. {
  94. option->state |= QStyle::State_Sunken;
  95. }
  96. if (this->isChecked() && !d->LookOffWhenChecked)
  97. {
  98. option->state |= QStyle::State_On;
  99. }
  100. if (!this->isDown())
  101. {
  102. option->state |= QStyle::State_Raised;
  103. }
  104. option->text = this->text();
  105. option->icon = this->icon();
  106. option->iconSize = QSize(this->style()->pixelMetric(QStyle::PM_IndicatorWidth, option, this),
  107. this->style()->pixelMetric(QStyle::PM_IndicatorHeight, option, this));
  108. int buttonHeight = this->buttonSizeHint().height();//qMax(this->fontMetrics().height(), option->iconSize.height());
  109. option->rect.setHeight(buttonHeight);
  110. }
  111. //-----------------------------------------------------------------------------
  112. ctkCollapsibleButton::ctkCollapsibleButton(QWidget* _parent)
  113. :QAbstractButton(_parent)
  114. , d_ptr(new ctkCollapsibleButtonPrivate(*this))
  115. {
  116. Q_D(ctkCollapsibleButton);
  117. d->init();
  118. }
  119. //-----------------------------------------------------------------------------
  120. ctkCollapsibleButton::ctkCollapsibleButton(const QString& title, QWidget* _parent)
  121. :QAbstractButton(_parent)
  122. , d_ptr(new ctkCollapsibleButtonPrivate(*this))
  123. {
  124. Q_D(ctkCollapsibleButton);
  125. d->init();
  126. this->setText(title);
  127. }
  128. //-----------------------------------------------------------------------------
  129. ctkCollapsibleButton::~ctkCollapsibleButton()
  130. {
  131. }
  132. //-----------------------------------------------------------------------------
  133. void ctkCollapsibleButton::setCollapsed(bool c)
  134. {
  135. if (!this->isCheckable())
  136. {
  137. // not sure if one should handle this case...
  138. this->collapse(c);
  139. return;
  140. }
  141. this->setChecked(!c);
  142. }
  143. //-----------------------------------------------------------------------------
  144. bool ctkCollapsibleButton::collapsed()const
  145. {
  146. Q_D(const ctkCollapsibleButton);
  147. return d->Collapsed;
  148. }
  149. //-----------------------------------------------------------------------------
  150. void ctkCollapsibleButton::setCollapsedHeight(int h)
  151. {
  152. Q_D(ctkCollapsibleButton);
  153. d->CollapsedHeight = h;
  154. this->updateGeometry();
  155. }
  156. //-----------------------------------------------------------------------------
  157. int ctkCollapsibleButton::collapsedHeight()const
  158. {
  159. Q_D(const ctkCollapsibleButton);
  160. return d->CollapsedHeight;
  161. }
  162. //-----------------------------------------------------------------------------
  163. void ctkCollapsibleButton::onToggled(bool checked)
  164. {
  165. if (this->isCheckable())
  166. {
  167. this->collapse(!checked);
  168. }
  169. }
  170. //-----------------------------------------------------------------------------
  171. void ctkCollapsibleButton::collapse(bool c)
  172. {
  173. Q_D(ctkCollapsibleButton);
  174. if (c == d->Collapsed)
  175. {
  176. return;
  177. }
  178. d->Collapsed = c;
  179. // we do that here as setVisible calls will correctly refresh the widget
  180. if (c)
  181. {
  182. d->MaximumHeight = this->maximumHeight();
  183. this->setMaximumHeight(this->sizeHint().height());
  184. //this->updateGeometry();
  185. }
  186. else
  187. {
  188. // restore maximumheight
  189. this->setMaximumHeight(d->MaximumHeight);
  190. this->updateGeometry();
  191. }
  192. QObjectList childList = this->children();
  193. for (int i = 0; i < childList.size(); ++i)
  194. {
  195. QObject *o = childList.at(i);
  196. if (!o->isWidgetType())
  197. {
  198. continue;
  199. }
  200. QWidget *w = static_cast<QWidget *>(o);
  201. w->setVisible(!c);
  202. }
  203. // this might be too many updates...
  204. QWidget* _parent = this->parentWidget();
  205. if (!d->Collapsed && (!_parent || !_parent->layout()))
  206. {
  207. this->resize(this->sizeHint());
  208. }
  209. else
  210. {
  211. this->updateGeometry();
  212. }
  213. //this->update(QRect(QPoint(0,0), this->sizeHint()));
  214. //this->repaint(QRect(QPoint(0,0), this->sizeHint()));
  215. emit contentsCollapsed(c);
  216. }
  217. //-----------------------------------------------------------------------------
  218. QFrame::Shape ctkCollapsibleButton::contentsFrameShape() const
  219. {
  220. Q_D(const ctkCollapsibleButton);
  221. return d->ContentsFrameShape;
  222. }
  223. //-----------------------------------------------------------------------------
  224. void ctkCollapsibleButton::setContentsFrameShape(QFrame::Shape s)
  225. {
  226. Q_D(ctkCollapsibleButton);
  227. d->ContentsFrameShape = s;
  228. }
  229. //-----------------------------------------------------------------------------
  230. QFrame::Shadow ctkCollapsibleButton::contentsFrameShadow() const
  231. {
  232. Q_D(const ctkCollapsibleButton);
  233. return d->ContentsFrameShadow;
  234. }
  235. //-----------------------------------------------------------------------------
  236. void ctkCollapsibleButton::setContentsFrameShadow(QFrame::Shadow s)
  237. {
  238. Q_D(ctkCollapsibleButton);
  239. d->ContentsFrameShadow = s;
  240. }
  241. //-----------------------------------------------------------------------------
  242. int ctkCollapsibleButton:: contentsLineWidth() const
  243. {
  244. Q_D(const ctkCollapsibleButton);
  245. return d->ContentsLineWidth;
  246. }
  247. //-----------------------------------------------------------------------------
  248. void ctkCollapsibleButton::setContentsLineWidth(int w)
  249. {
  250. Q_D(ctkCollapsibleButton);
  251. d->ContentsLineWidth = w;
  252. }
  253. //-----------------------------------------------------------------------------
  254. int ctkCollapsibleButton::contentsMidLineWidth() const
  255. {
  256. Q_D(const ctkCollapsibleButton);
  257. return d->ContentsMidLineWidth;
  258. }
  259. //-----------------------------------------------------------------------------
  260. void ctkCollapsibleButton::setContentsMidLineWidth(int w)
  261. {
  262. Q_D(ctkCollapsibleButton);
  263. d->ContentsMidLineWidth = w;
  264. }
  265. //-----------------------------------------------------------------------------
  266. void ctkCollapsibleButton::setButtonTextAlignment(Qt::Alignment textAlignment)
  267. {
  268. Q_D(ctkCollapsibleButton);
  269. d->TextAlignment = textAlignment;
  270. this->update();
  271. }
  272. //-----------------------------------------------------------------------------
  273. Qt::Alignment ctkCollapsibleButton::buttonTextAlignment()const
  274. {
  275. Q_D(const ctkCollapsibleButton);
  276. return d->TextAlignment;
  277. }
  278. //-----------------------------------------------------------------------------
  279. void ctkCollapsibleButton::setIndicatorAlignment(Qt::Alignment indicatorAlignment)
  280. {
  281. Q_D(ctkCollapsibleButton);
  282. d->IndicatorAlignment = indicatorAlignment;
  283. this->update();
  284. }
  285. //-----------------------------------------------------------------------------
  286. Qt::Alignment ctkCollapsibleButton::indicatorAlignment()const
  287. {
  288. Q_D(const ctkCollapsibleButton);
  289. return d->IndicatorAlignment;
  290. }
  291. //-----------------------------------------------------------------------------
  292. QSize ctkCollapsibleButton::buttonSizeHint()const
  293. {
  294. int w = 0, h = 0;
  295. QStyleOptionButton opt;
  296. opt.initFrom(this);
  297. // indicator
  298. QSize indicatorSize = QSize(style()->pixelMetric(QStyle::PM_IndicatorWidth, &opt, this),
  299. style()->pixelMetric(QStyle::PM_IndicatorHeight, &opt, this));
  300. int indicatorSpacing = style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &opt, this);
  301. int ih = indicatorSize.height();
  302. int iw = indicatorSize.width() + indicatorSpacing;
  303. w += iw;
  304. h = qMax(h, ih);
  305. // text
  306. QString string(this->text());
  307. bool empty = string.isEmpty();
  308. if (empty)
  309. {
  310. string = QString::fromLatin1("XXXX");
  311. }
  312. QFontMetrics fm = this->fontMetrics();
  313. QSize sz = fm.size(Qt::TextShowMnemonic, string);
  314. if(!empty || !w)
  315. {
  316. w += sz.width();
  317. }
  318. h = qMax(h, sz.height());
  319. //opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height
  320. QSize buttonSize = (style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), this).
  321. expandedTo(QApplication::globalStrut()));
  322. return buttonSize;
  323. }
  324. //-----------------------------------------------------------------------------
  325. QSize ctkCollapsibleButton::minimumSizeHint()const
  326. {
  327. Q_D(const ctkCollapsibleButton);
  328. QSize buttonSize = this->buttonSizeHint();
  329. if (d->Collapsed)
  330. {
  331. return buttonSize + QSize(0,d->CollapsedHeight);
  332. }
  333. // open
  334. if (this->layout() == 0)
  335. {// no layout, means the button is empty ?
  336. return buttonSize;
  337. }
  338. QSize s = this->QAbstractButton::minimumSizeHint();
  339. return s.expandedTo(buttonSize);
  340. }
  341. //-----------------------------------------------------------------------------
  342. QSize ctkCollapsibleButton::sizeHint()const
  343. {
  344. Q_D(const ctkCollapsibleButton);
  345. QSize buttonSize = this->buttonSizeHint();
  346. if (d->Collapsed)
  347. {
  348. return buttonSize + QSize(0,d->CollapsedHeight);
  349. }
  350. // open
  351. // QAbstractButton works well only if a layout is set
  352. QSize s = this->QAbstractButton::sizeHint();
  353. return s.expandedTo(buttonSize + QSize(0, d->CollapsedHeight));
  354. }
  355. //-----------------------------------------------------------------------------
  356. void ctkCollapsibleButton::paintEvent(QPaintEvent * _event)
  357. {
  358. Q_D(ctkCollapsibleButton);
  359. QPainter p(this);
  360. // Draw Button
  361. QStyleOptionButton opt;
  362. this->initStyleOption(&opt);
  363. // We don't want to have the highlight effect on the button when mouse is
  364. // over a child. We want the highlight effect only when the mouse is just
  365. // over itself.
  366. // same as this->underMouse()
  367. bool exclusiveMouseOver = false;
  368. if (opt.state & QStyle::State_MouseOver)
  369. {
  370. QRect buttonRect = opt.rect;
  371. QList<QWidget*> _children = this->findChildren<QWidget*>();
  372. QList<QWidget*>::ConstIterator it;
  373. for (it = _children.constBegin(); it != _children.constEnd(); ++it )
  374. {
  375. if ((*it)->underMouse())
  376. {
  377. // the mouse has been moved from the collapsible button to one
  378. // of its children. The paint event rect is the child rect, this
  379. // is why we have to request another paint event to redraw the
  380. // button to remove the highlight effect.
  381. if (!_event->rect().contains(buttonRect))
  382. {// repaint the button rect.
  383. this->update(buttonRect);
  384. }
  385. opt.state &= ~QStyle::State_MouseOver;
  386. exclusiveMouseOver = true;
  387. break;
  388. }
  389. }
  390. if (d->ExclusiveMouseOver && !exclusiveMouseOver)
  391. {
  392. // the mouse is over the widget, but not over the children. As it
  393. // has been de-highlighted in the past, we should refresh the button
  394. // rect to re-highlight the button.
  395. if (!_event->rect().contains(buttonRect))
  396. {// repaint the button rect.
  397. this->update(buttonRect);
  398. }
  399. }
  400. }
  401. d->ExclusiveMouseOver = exclusiveMouseOver;
  402. QSize indicatorSize = QSize(style()->pixelMetric(QStyle::PM_IndicatorWidth, &opt, this),
  403. style()->pixelMetric(QStyle::PM_IndicatorHeight, &opt, this));
  404. opt.iconSize = indicatorSize;
  405. style()->drawControl(QStyle::CE_PushButtonBevel, &opt, &p, this);
  406. // TBD is PE_PanelButtonCommand better ?
  407. //style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, &p, this);
  408. int buttonHeight = opt.rect.height();
  409. uint tf = d->TextAlignment;
  410. if (this->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
  411. {
  412. tf |= Qt::TextShowMnemonic;
  413. }
  414. else
  415. {
  416. tf |= Qt::TextHideMnemonic;
  417. }
  418. int textWidth = opt.fontMetrics.boundingRect(opt.rect, tf, opt.text).width();
  419. int indicatorSpacing = this->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &opt, this);
  420. int buttonMargin = this->style()->pixelMetric(QStyle::PM_ButtonMargin, &opt, this);
  421. // Draw Indicator
  422. QStyleOption indicatorOpt;
  423. indicatorOpt.init(this);
  424. if (d->IndicatorAlignment & Qt::AlignLeft)
  425. {
  426. indicatorOpt.rect = QRect((buttonHeight - indicatorSize.width()) / 2,
  427. (buttonHeight - indicatorSize.height()) / 2,
  428. indicatorSize.width(), indicatorSize.height());
  429. }
  430. else if (d->IndicatorAlignment & Qt::AlignHCenter)
  431. {
  432. int w = indicatorSize.width();
  433. if (!opt.text.isEmpty() && (d->TextAlignment & Qt::AlignHCenter))
  434. {
  435. w += textWidth + indicatorSpacing;
  436. }
  437. indicatorOpt.rect = QRect(opt.rect.x()+ opt.rect.width() /2 - w / 2,
  438. (buttonHeight - indicatorSize.height()) / 2,
  439. indicatorSize.width(), indicatorSize.height());
  440. if (d->TextAlignment & Qt::AlignLeft &&
  441. indicatorOpt.rect.left() < opt.rect.x() + buttonMargin + textWidth)
  442. {
  443. indicatorOpt.rect.moveLeft(opt.rect.x() + buttonMargin + textWidth);
  444. }
  445. else if (d->TextAlignment & Qt::AlignRight &&
  446. indicatorOpt.rect.right() > opt.rect.right() - buttonMargin - textWidth)
  447. {
  448. indicatorOpt.rect.moveRight(opt.rect.right() - buttonMargin - textWidth);
  449. }
  450. }
  451. else if (d->IndicatorAlignment & Qt::AlignRight)
  452. {
  453. indicatorOpt.rect = QRect(opt.rect.width() - (buttonHeight - indicatorSize.width()) / 2
  454. - indicatorSize.width(),
  455. (buttonHeight - indicatorSize.height()) / 2,
  456. indicatorSize.width(), indicatorSize.height());
  457. }
  458. if (d->Collapsed)
  459. {
  460. style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &indicatorOpt, &p, this);
  461. }
  462. else
  463. {
  464. style()->drawPrimitive(QStyle::PE_IndicatorArrowUp, &indicatorOpt, &p, this);
  465. }
  466. // Draw Text
  467. if (d->TextAlignment & Qt::AlignLeft)
  468. {
  469. if (d->IndicatorAlignment & Qt::AlignLeft)
  470. {
  471. opt.rect.setLeft(indicatorOpt.rect.right() + indicatorSpacing);
  472. }
  473. else
  474. {
  475. opt.rect.setLeft(opt.rect.x() + buttonMargin);
  476. }
  477. }
  478. else if (d->TextAlignment & Qt::AlignHCenter)
  479. {
  480. if (d->IndicatorAlignment & Qt::AlignHCenter)
  481. {
  482. opt.rect.setLeft(indicatorOpt.rect.right() + indicatorSpacing);
  483. }
  484. else
  485. {
  486. opt.rect.setLeft(opt.rect.x() + opt.rect.width() / 2 - textWidth / 2);
  487. if (d->IndicatorAlignment & Qt::AlignLeft)
  488. {
  489. opt.rect.setLeft( qMax(indicatorOpt.rect.right() + indicatorSpacing, opt.rect.left()) );
  490. }
  491. }
  492. }
  493. else if (d->TextAlignment & Qt::AlignRight)
  494. {
  495. if (d->IndicatorAlignment & Qt::AlignRight)
  496. {
  497. opt.rect.setLeft(indicatorOpt.rect.left() - indicatorSpacing - textWidth);
  498. }
  499. else
  500. {
  501. opt.rect.setLeft(opt.rect.right() - buttonMargin - textWidth);
  502. }
  503. }
  504. // all the computations have been made infering the text would be left oriented
  505. tf &= ~Qt::AlignHCenter & ~Qt::AlignRight;
  506. tf |= Qt::AlignLeft;
  507. style()->drawItemText(&p, opt.rect, tf, opt.palette, (opt.state & QStyle::State_Enabled),
  508. opt.text, QPalette::ButtonText);
  509. // Draw Frame around contents
  510. QStyleOptionFrameV3 fopt;
  511. fopt.init(this);
  512. // HACK: on some styles, the frame doesn't exactly touch the button.
  513. // this is because the button has some kind of extra border.
  514. if (qobject_cast<QCleanlooksStyle*>(this->style()) != 0)
  515. {
  516. fopt.rect.setTop(buttonHeight - 1);
  517. }
  518. else
  519. {
  520. fopt.rect.setTop(buttonHeight);
  521. }
  522. fopt.frameShape = d->ContentsFrameShape;
  523. switch (d->ContentsFrameShadow)
  524. {
  525. case QFrame::Sunken:
  526. fopt.state |= QStyle::State_Sunken;
  527. break;
  528. case QFrame::Raised:
  529. fopt.state |= QStyle::State_Raised;
  530. break;
  531. default:
  532. case QFrame::Plain:
  533. break;
  534. }
  535. fopt.lineWidth = d->ContentsLineWidth;
  536. fopt.midLineWidth = d->ContentsMidLineWidth;
  537. style()->drawControl(QStyle::CE_ShapedFrame, &fopt, &p, this);
  538. }
  539. //-----------------------------------------------------------------------------
  540. bool ctkCollapsibleButton::hitButton(const QPoint & _pos)const
  541. {
  542. QStyleOptionButton opt;
  543. this->initStyleOption(&opt);
  544. return opt.rect.contains(_pos);
  545. }
  546. //-----------------------------------------------------------------------------
  547. void ctkCollapsibleButton::childEvent(QChildEvent* c)
  548. {
  549. Q_D(ctkCollapsibleButton);
  550. if(c && c->type() == QEvent::ChildAdded)
  551. {
  552. if (c->child() && c->child()->isWidgetType())
  553. {
  554. QWidget *w = static_cast<QWidget*>(c->child());
  555. w->setVisible(!d->Collapsed);
  556. }
  557. }
  558. QWidget::childEvent(c);
  559. }
  560. //-----------------------------------------------------------------------------
  561. bool ctkCollapsibleButton::event(QEvent *event)
  562. {
  563. if (event->type() == QEvent::StyleChange
  564. || event->type() == QEvent::FontChange
  565. #ifdef Q_WS_MAC
  566. || event->type() == QEvent::MacSizeChange
  567. #endif
  568. )
  569. {
  570. this->setContentsMargins(0, this->buttonSizeHint().height(),0 , 0);
  571. if (this->collapsed())
  572. {
  573. this->setMaximumHeight(this->sizeHint().height());
  574. }
  575. }
  576. return QAbstractButton::event(event);
  577. }