/src/libtomahawk/playlist/topbar/lineedit.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 230 lines · 175 code · 28 blank · 27 comment · 25 complexity · c0d6f82ba1b1f555e2090b7917f29dab MD5 · raw file

  1. /**
  2. * Copyright (c) 2008 - 2009, Benjamin C. Meyer <ben@meyerhome.net>
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * 3. Neither the name of the Benjamin Meyer nor the names of its contributors
  13. * may be used to endorse or promote products derived from this software
  14. * without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #include "lineedit.h"
  29. #include "lineedit_p.h"
  30. #include <qevent.h>
  31. #include <qlayout.h>
  32. #include <qstyleoption.h>
  33. #include <qpainter.h>
  34. SideWidget::SideWidget(QWidget *parent)
  35. : QWidget(parent)
  36. {
  37. }
  38. bool SideWidget::event(QEvent *event)
  39. {
  40. if (event->type() == QEvent::LayoutRequest)
  41. emit sizeHintChanged();
  42. return QWidget::event(event);
  43. }
  44. LineEdit::LineEdit(QWidget *parent)
  45. : QLineEdit(parent)
  46. , m_leftLayout(0)
  47. , m_rightLayout(0)
  48. {
  49. init();
  50. }
  51. LineEdit::LineEdit(const QString &contents, QWidget *parent)
  52. : QLineEdit(contents, parent)
  53. , m_leftWidget(0)
  54. , m_rightWidget(0)
  55. , m_leftLayout(0)
  56. , m_rightLayout(0)
  57. {
  58. init();
  59. }
  60. void LineEdit::init()
  61. {
  62. m_leftWidget = new SideWidget(this);
  63. m_leftWidget->resize(0, 0);
  64. m_leftLayout = new QHBoxLayout(m_leftWidget);
  65. m_leftLayout->setContentsMargins(0, 0, 0, 0);
  66. if (isRightToLeft())
  67. m_leftLayout->setDirection(QBoxLayout::RightToLeft);
  68. else
  69. m_leftLayout->setDirection(QBoxLayout::LeftToRight);
  70. m_leftLayout->setSizeConstraint(QLayout::SetFixedSize);
  71. m_rightWidget = new SideWidget(this);
  72. m_rightWidget->resize(0, 0);
  73. m_rightLayout = new QHBoxLayout(m_rightWidget);
  74. if (isRightToLeft())
  75. m_rightLayout->setDirection(QBoxLayout::RightToLeft);
  76. else
  77. m_rightLayout->setDirection(QBoxLayout::LeftToRight);
  78. m_rightLayout->setContentsMargins(0, 0, 0, 0);
  79. QSpacerItem *horizontalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
  80. m_rightLayout->addItem(horizontalSpacer);
  81. setWidgetSpacing(3);
  82. connect(m_leftWidget, SIGNAL(sizeHintChanged()),
  83. this, SLOT(updateTextMargins()));
  84. connect(m_rightWidget, SIGNAL(sizeHintChanged()),
  85. this, SLOT(updateTextMargins()));
  86. }
  87. bool LineEdit::event(QEvent *event)
  88. {
  89. if (event->type() == QEvent::LayoutDirectionChange) {
  90. if (isRightToLeft()) {
  91. m_leftLayout->setDirection(QBoxLayout::RightToLeft);
  92. m_rightLayout->setDirection(QBoxLayout::RightToLeft);
  93. } else {
  94. m_leftLayout->setDirection(QBoxLayout::LeftToRight);
  95. m_rightLayout->setDirection(QBoxLayout::LeftToRight);
  96. }
  97. }
  98. return QLineEdit::event(event);
  99. }
  100. void LineEdit::addWidget(QWidget *widget, WidgetPosition position)
  101. {
  102. if (!widget)
  103. return;
  104. bool rtl = isRightToLeft();
  105. if (rtl)
  106. position = (position == LeftSide) ? RightSide : LeftSide;
  107. if (position == LeftSide) {
  108. m_leftLayout->addWidget(widget);
  109. } else {
  110. m_rightLayout->insertWidget(1, widget);
  111. }
  112. }
  113. void LineEdit::removeWidget(QWidget *widget)
  114. {
  115. if (!widget)
  116. return;
  117. m_leftLayout->removeWidget(widget);
  118. m_rightLayout->removeWidget(widget);
  119. widget->hide();
  120. }
  121. void LineEdit::setWidgetSpacing(int spacing)
  122. {
  123. m_leftLayout->setSpacing(spacing);
  124. m_rightLayout->setSpacing(spacing);
  125. updateTextMargins();
  126. }
  127. int LineEdit::widgetSpacing() const
  128. {
  129. return m_leftLayout->spacing();
  130. }
  131. int LineEdit::textMargin(WidgetPosition position) const
  132. {
  133. int spacing = m_rightLayout->spacing();
  134. int w = 0;
  135. if (position == LeftSide)
  136. w = m_leftWidget->sizeHint().width();
  137. else
  138. w = m_rightWidget->sizeHint().width();
  139. if (w == 0)
  140. return 0;
  141. return w + spacing * 2;
  142. }
  143. void LineEdit::updateTextMargins()
  144. {
  145. int left = textMargin(LineEdit::LeftSide);
  146. int right = textMargin(LineEdit::RightSide);
  147. int top = 0;
  148. int bottom = 0;
  149. setTextMargins(left, top, right, bottom);
  150. updateSideWidgetLocations();
  151. }
  152. void LineEdit::updateSideWidgetLocations()
  153. {
  154. QStyleOptionFrameV2 opt;
  155. initStyleOption(&opt);
  156. QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &opt, this);
  157. int spacing = m_rightLayout->spacing();
  158. textRect.adjust(spacing, 0, -spacing, 0);
  159. int left = textMargin(LineEdit::LeftSide);
  160. int midHeight = textRect.center().y() + 1;
  161. if (m_leftLayout->count() > 0) {
  162. int leftHeight = midHeight - m_leftWidget->height() / 2;
  163. int leftWidth = m_leftWidget->width();
  164. if (leftWidth == 0)
  165. leftHeight = midHeight - m_leftWidget->sizeHint().height() / 2;
  166. m_leftWidget->move(textRect.x(), leftHeight);
  167. }
  168. textRect.setX(left);
  169. textRect.setY(midHeight - m_rightWidget->sizeHint().height() / 2);
  170. textRect.setHeight(m_rightWidget->sizeHint().height());
  171. m_rightWidget->setGeometry(textRect);
  172. }
  173. void LineEdit::resizeEvent(QResizeEvent *event)
  174. {
  175. updateSideWidgetLocations();
  176. QLineEdit::resizeEvent(event);
  177. }
  178. QString LineEdit::inactiveText() const
  179. {
  180. return m_inactiveText;
  181. }
  182. void LineEdit::setInactiveText(const QString &text)
  183. {
  184. m_inactiveText = text;
  185. }
  186. void LineEdit::paintEvent(QPaintEvent *event)
  187. {
  188. QLineEdit::paintEvent(event);
  189. if (text().isEmpty() && !m_inactiveText.isEmpty() && !hasFocus()) {
  190. QStyleOptionFrameV2 panel;
  191. initStyleOption(&panel);
  192. QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
  193. int horizontalMargin = 2;
  194. textRect.adjust(horizontalMargin, 0, 0, 0);
  195. int left = textMargin(LineEdit::LeftSide);
  196. int right = textMargin(LineEdit::RightSide);
  197. textRect.adjust(left, 0, -right, 0);
  198. QPainter painter(this);
  199. painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color());
  200. painter.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, m_inactiveText);
  201. }
  202. }