windowbar.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
  2. // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
  3. // SPDX-License-Identifier: Apache-2.0
  4. #include "windowbar.h"
  5. #include "windowbar_p.h"
  6. #include <QtCore/QDebug>
  7. #include <QtCore/QLocale>
  8. #include <QtGui/QtEvents>
  9. namespace QWK {
  10. WindowBarPrivate::WindowBarPrivate() {
  11. w = nullptr;
  12. autoTitle = true;
  13. autoIcon = false;
  14. }
  15. WindowBarPrivate::~WindowBarPrivate() = default;
  16. void WindowBarPrivate::init() {
  17. Q_Q(WindowBar);
  18. layout = new QHBoxLayout();
  19. if (QLocale::system().textDirection() == Qt::RightToLeft) {
  20. layout->setDirection(QBoxLayout::RightToLeft);
  21. }
  22. layout->setContentsMargins(QMargins());
  23. layout->setSpacing(0);
  24. for (int i = IconButton; i <= CloseButton; ++i) {
  25. insertDefaultSpace(i);
  26. }
  27. q->setLayout(layout);
  28. }
  29. void WindowBarPrivate::setWidgetAt(int index, QWidget *widget) {
  30. auto item = layout->takeAt(index);
  31. auto orgWidget = item->widget();
  32. if (orgWidget) {
  33. orgWidget->deleteLater();
  34. }
  35. delete item;
  36. if (!widget) {
  37. insertDefaultSpace(index);
  38. } else {
  39. layout->insertWidget(index, widget);
  40. }
  41. }
  42. QWidget *WindowBarPrivate::takeWidgetAt(int index) {
  43. auto item = layout->itemAt(index);
  44. auto orgWidget = item->widget();
  45. if (orgWidget) {
  46. item = layout->takeAt(index);
  47. delete item;
  48. insertDefaultSpace(index);
  49. }
  50. return orgWidget;
  51. }
  52. WindowBar::WindowBar(QWidget *parent) : WindowBar(*new WindowBarPrivate(), parent) {
  53. }
  54. WindowBar::~WindowBar() = default;
  55. QMenuBar *WindowBar::menuBar() const {
  56. Q_D(const WindowBar);
  57. return static_cast<QMenuBar *>(d->widgetAt(WindowBarPrivate::MenuWidget));
  58. }
  59. QLabel *WindowBar::titleLabel() const {
  60. Q_D(const WindowBar);
  61. return static_cast<QLabel *>(d->widgetAt(WindowBarPrivate::TitleLabel));
  62. }
  63. QAbstractButton *WindowBar::iconButton() const {
  64. Q_D(const WindowBar);
  65. return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::IconButton));
  66. }
  67. QAbstractButton *WindowBar::pinButton() const {
  68. Q_D(const WindowBar);
  69. return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::PinButton));
  70. }
  71. QAbstractButton *WindowBar::minButton() const {
  72. Q_D(const WindowBar);
  73. return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimizeButton));
  74. }
  75. QAbstractButton *WindowBar::maxButton() const {
  76. Q_D(const WindowBar);
  77. return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximizeButton));
  78. }
  79. QAbstractButton *WindowBar::closeButton() const {
  80. Q_D(const WindowBar);
  81. return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::CloseButton));
  82. }
  83. void WindowBar::setMenuBar(QMenuBar *menuBar) {
  84. Q_D(WindowBar);
  85. auto org = takeMenuBar();
  86. if (org)
  87. org->deleteLater();
  88. if (!menuBar)
  89. return;
  90. d->setWidgetAt(WindowBarPrivate::MenuWidget, menuBar);
  91. menuBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
  92. }
  93. void WindowBar::setTitleLabel(QLabel *label) {
  94. Q_D(WindowBar);
  95. auto org = takeTitleLabel();
  96. if (org)
  97. org->deleteLater();
  98. if (!label)
  99. return;
  100. d->setWidgetAt(WindowBarPrivate::TitleLabel, label);
  101. if (d->autoTitle && d->w)
  102. label->setText(d->w->windowTitle());
  103. label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
  104. }
  105. void WindowBar::setIconButton(QAbstractButton *btn) {
  106. Q_D(WindowBar);
  107. auto org = takeIconButton();
  108. if (org)
  109. org->deleteLater();
  110. if (!btn)
  111. return;
  112. d->setWidgetAt(WindowBarPrivate::IconButton, btn);
  113. if (d->autoIcon && d->w)
  114. btn->setIcon(d->w->windowIcon());
  115. btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
  116. }
  117. void WindowBar::setPinButton(QAbstractButton *btn) {
  118. Q_D(WindowBar);
  119. auto org = takePinButton();
  120. if (org)
  121. org->deleteLater();
  122. if (!btn)
  123. return;
  124. d->setWidgetAt(WindowBarPrivate::PinButton, btn);
  125. connect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
  126. }
  127. void WindowBar::setMinButton(QAbstractButton *btn) {
  128. Q_D(WindowBar);
  129. auto org = takeMinButton();
  130. if (org)
  131. org->deleteLater();
  132. if (!btn)
  133. return;
  134. d->setWidgetAt(WindowBarPrivate::MinimizeButton, btn);
  135. connect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
  136. }
  137. void WindowBar::setMaxButton(QAbstractButton *btn) {
  138. Q_D(WindowBar);
  139. auto org = takeMaxButton();
  140. if (org)
  141. org->deleteLater();
  142. if (!btn)
  143. return;
  144. d->setWidgetAt(WindowBarPrivate::MaximizeButton, btn);
  145. connect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
  146. }
  147. void WindowBar::setCloseButton(QAbstractButton *btn) {
  148. Q_D(WindowBar);
  149. auto org = takeCloseButton();
  150. if (org)
  151. org->deleteLater();
  152. if (!btn)
  153. return;
  154. d->setWidgetAt(WindowBarPrivate::CloseButton, btn);
  155. connect(btn, &QAbstractButton::clicked, this, &WindowBar::closeRequested);
  156. }
  157. QMenuBar *WindowBar::takeMenuBar() {
  158. Q_D(WindowBar);
  159. return static_cast<QMenuBar *>(d->takeWidgetAt(WindowBarPrivate::MenuWidget));
  160. }
  161. QLabel *WindowBar::takeTitleLabel() {
  162. Q_D(WindowBar);
  163. return static_cast<QLabel *>(d->takeWidgetAt(WindowBarPrivate::TitleLabel));
  164. }
  165. QAbstractButton *WindowBar::takeIconButton() {
  166. Q_D(WindowBar);
  167. return static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::IconButton));
  168. }
  169. QAbstractButton *WindowBar::takePinButton() {
  170. Q_D(WindowBar);
  171. auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::PinButton));
  172. if (!btn) {
  173. return nullptr;
  174. }
  175. disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
  176. return btn;
  177. }
  178. QAbstractButton *WindowBar::takeMinButton() {
  179. Q_D(WindowBar);
  180. auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimizeButton));
  181. if (!btn) {
  182. return nullptr;
  183. }
  184. disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
  185. return btn;
  186. }
  187. QAbstractButton *WindowBar::takeMaxButton() {
  188. Q_D(WindowBar);
  189. auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximizeButton));
  190. if (!btn) {
  191. return nullptr;
  192. }
  193. disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
  194. return btn;
  195. }
  196. QAbstractButton *WindowBar::takeCloseButton() {
  197. Q_D(WindowBar);
  198. auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::CloseButton));
  199. if (!btn) {
  200. return nullptr;
  201. }
  202. disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::closeRequested);
  203. return btn;
  204. }
  205. QWidget *WindowBar::hostWidget() const {
  206. Q_D(const WindowBar);
  207. return d->w;
  208. }
  209. void WindowBar::setHostWidget(QWidget *w) {
  210. Q_D(WindowBar);
  211. QWidget *org = d->w;
  212. if (org) {
  213. org->removeEventFilter(this);
  214. }
  215. d_ptr->w = w;
  216. if (w) {
  217. w->installEventFilter(this);
  218. }
  219. }
  220. bool WindowBar::titleFollowWindow() const {
  221. Q_D(const WindowBar);
  222. return d->autoTitle;
  223. }
  224. void WindowBar::setTitleFollowWindow(bool value) {
  225. Q_D(WindowBar);
  226. d->autoTitle = value;
  227. }
  228. bool WindowBar::iconFollowWindow() const {
  229. Q_D(const WindowBar);
  230. return d->autoIcon;
  231. }
  232. void WindowBar::setIconFollowWindow(bool value) {
  233. Q_D(WindowBar);
  234. d->autoIcon = value;
  235. }
  236. bool WindowBar::eventFilter(QObject *obj, QEvent *event) {
  237. Q_D(WindowBar);
  238. auto w = d->w;
  239. if (obj == w) {
  240. QAbstractButton *iconBtn = iconButton();
  241. QLabel *label = titleLabel();
  242. QAbstractButton *maxBtn = maxButton();
  243. switch (event->type()) {
  244. case QEvent::WindowIconChange: {
  245. if (d_ptr->autoIcon && iconBtn) {
  246. iconBtn->setIcon(w->windowIcon());
  247. iconChanged(w->windowIcon());
  248. }
  249. break;
  250. }
  251. case QEvent::WindowTitleChange: {
  252. if (d_ptr->autoTitle && label) {
  253. label->setText(w->windowTitle());
  254. titleChanged(w->windowTitle());
  255. }
  256. break;
  257. }
  258. case QEvent::WindowStateChange: {
  259. if (maxBtn) {
  260. maxBtn->setChecked(w->isMaximized());
  261. }
  262. break;
  263. }
  264. default:
  265. break;
  266. }
  267. }
  268. return QWidget::eventFilter(obj, event);
  269. }
  270. void WindowBar::titleChanged(const QString &text) {
  271. Q_UNUSED(text)
  272. }
  273. void WindowBar::iconChanged(const QIcon &icon){Q_UNUSED(icon)}
  274. WindowBar::WindowBar(WindowBarPrivate &d, QWidget *parent)
  275. : QFrame(parent), d_ptr(&d) {
  276. d.q_ptr = this;
  277. d.init();
  278. }
  279. }