bool m_active = true;
bool m_showPlacesSelector = false;
bool m_showFullPath = false;
+ bool m_backgroundEnabled = true;
- int m_padding = 4;
+ int m_padding = 5;
struct {
bool showHidden = false;
{
m_layout->setSpacing(0);
m_layout->setContentsMargins(0, 0, 0, 0);
+ QStyleOption option;
+ option.initFrom(q);
q->connect(m_coreUrlNavigator, &KCoreUrlNavigator::currentLocationUrlChanged, q, [this]() {
Q_EMIT q->urlChanged(m_coreUrlNavigator->currentLocationUrl());
m_layout->addWidget(m_dropDownButton);
m_layout->addWidget(m_pathBox, 1);
m_layout->addWidget(m_badgeWidgetContainer);
+ m_layout->addSpacing(q->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, &option, q));
m_layout->addWidget(m_toggleEditableMode);
q->setContextMenuPolicy(Qt::CustomContextMenu);
// Make sure pathBox does not portrude outside of the above frameLineEdit background
const int paddingLeft = q->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
const int paddingRight = q->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
- q->setContentsMargins(paddingLeft, 0, paddingRight, 0);
+ q->rect().adjust(0, -1, 0, 1);
+ q->setContentsMargins(paddingLeft, 1, paddingRight, 1);
m_pathBox->setContentsMargins(paddingLeft, 0, paddingRight, 0);
}
m_toggleEditableMode->setChecked(m_editable);
updateContent();
if (q->isUrlEditable()) {
+ m_pathBox->setFixedHeight(m_badgeWidgetContainer->height());
m_pathBox->setFocus();
}
q->requestActivation();
Q_EMIT q->editableStateChanged(m_editable);
+ // Make sure the colors are updated
+ q->update();
}
void KUrlNavigatorPrivate::dropUrls(const QUrl &destination, QDropEvent *event, KUrlNavigatorButton *dropButton)
// Subtract all widgets from the available width, that must be shown anyway
// Make sure to take the padding into account
- int availableWidth = q->width() - (m_padding * 2) - m_toggleEditableMode->minimumWidth();
+ int availableWidth = q->width() - m_toggleEditableMode->minimumWidth();
availableWidth -= m_badgeWidgetContainer->width();
availableWidth -= m_schemes->width();
}
- // Check whether buttons must be hidden at all...
- int requiredButtonWidth = 0;
- for (const auto *button : std::as_const(m_navButtons)) {
- requiredButtonWidth += button->minimumWidth();
- }
+ availableWidth -= m_dropDownButton->width();
- if (requiredButtonWidth > availableWidth) {
- // At least one button must be hidden. This implies that the
- // drop-down button must get visible, which again decreases the
- // available width.
- availableWidth -= m_dropDownButton->width();
- }
+ // Count the paddings of previous button and current button
+ availableWidth -= m_padding * 4;
// Hide buttons...
bool isLastButton = true;
void KUrlNavigatorPrivate::updateTabOrder()
{
QMultiMap<int, QWidget *> visibleChildrenSortedByX;
- const auto childWidgets = q->findChildren<QWidget *>();
+ const auto childWidgets = q->findChildren<KUrlNavigatorButtonBase *>();
for (auto childWidget : childWidgets) {
if (childWidget->isVisible()) {
if (q->layoutDirection() == Qt::LeftToRight) {
}
}
+void KUrlNavigator::setBackgroundEnabled(bool enabled)
+{
+ d->m_backgroundEnabled = enabled;
+}
+
+bool KUrlNavigator::isBackgroundEnabled() const
+{
+ return d->m_backgroundEnabled;
+}
+
void KUrlNavigator::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
QStyleOptionFrame option;
option.initFrom(this);
- option.state = QStyle::State_Sunken;
+ option.state = QStyle::State_None;
if (hasFocus()) {
option.palette.setColor(QPalette::Window, palette().color(QPalette::Highlight));
}
- // Adjust the rectangle due to how QRect coordinates work
- option.rect = option.rect.adjusted(1, 0, -1, 0);
- // Draw the background
- style()->drawPrimitive(QStyle::PE_FrameLineEdit, &option, &painter, this);
+ if (d->m_backgroundEnabled) {
+ // Draw primitive always, but change color if not editable
+ if (!d->m_editable) {
+ option.palette.setColor(QPalette::Base, palette().alternateBase().color());
+ }
+ style()->drawPrimitive(QStyle::PE_FrameLineEdit, &option, &painter, this);
+ } else {
+ // Draw primitive only for the input field
+ if (d->m_editable) {
+ style()->drawPrimitive(QStyle::PE_FrameLineEdit, &option, &painter, this);
+ }
+ }
}
#include "moc_kurlnavigator.cpp"
KUrlNavigatorButton::KUrlNavigatorButton(const QUrl &url, KUrlNavigator *parent)
: KUrlNavigatorButtonBase(parent)
- , m_hoverOverIcon(false)
+ , m_hoverOverArrow(false)
+ , m_hoverOverButton(false)
, m_pendingTextChange(false)
, m_replaceButton(false)
, m_showMnemonic(false)
, m_subDir()
, m_openSubDirsTimer(nullptr)
, m_subDirsJob(nullptr)
- , m_padding(10)
+ , m_padding(5)
{
setAcceptDrops(true);
setUrl(url);
// preferred width is textWidth, iconWidth and padding combined
// add extra padding in end to make sure the space between divider and button is consistent
// the first padding is used between icon and text, second in the end of text
- const int width = QFontMetrics(adjustedFont).size(Qt::TextSingleLine, plainText()).width() + iconWidth() + (m_padding * 2);
+ const int width = m_padding + textWidth() + arrowWidth() + m_padding;
return QSize(width, KUrlNavigatorButtonBase::sizeHint().height());
}
painter.setFont(adjustedFont);
int buttonWidth = width();
+ int arrowWidth = KUrlNavigatorButton::arrowWidth();
+
int preferredWidth = sizeHint().width();
if (preferredWidth < minimumWidth()) {
preferredWidth = minimumWidth();
buttonWidth = preferredWidth;
}
const int buttonHeight = height();
-
const QColor fgColor = foregroundColor();
- drawHoverBackground(&painter);
-
- int textLeft = 0;
- int textWidth = buttonWidth;
-
const bool leftToRight = (layoutDirection() == Qt::LeftToRight);
- // draw folder icon
- const int iconW = iconWidth();
- const int iconX = !leftToRight ? (buttonWidth - iconW) - m_padding / 2 : m_padding / 2;
- const int iconY = (buttonHeight - iconW) / 2;
-
- QStyleOption option;
- option.initFrom(this);
- option.rect = QRect(iconX, iconY, iconW, iconW);
- option.palette = palette();
- option.palette.setColor(QPalette::Text, fgColor);
- option.palette.setColor(QPalette::WindowText, fgColor);
- option.palette.setColor(QPalette::ButtonText, fgColor);
-
- if (m_hoverOverIcon) {
- option.rect = QRect(iconX - m_padding / 2, 0, iconW + m_padding, buttonHeight).marginsRemoved(QMargins(0, 2, 0, 2));
- style()->drawPrimitive(QStyle::PE_PanelButtonTool, &option, &painter, this);
- }
-
- const int widthModifier = iconW + m_padding / 2;
- auto pixmap = icon().pixmap(iconSize(), devicePixelRatioF());
- style()->drawItemPixmap(&painter, QRect(iconX, iconY, iconW, iconW), Qt::AlignCenter, pixmap);
+ // Prepare sizes for icon
+ QRect textRect;
+ const int textRectWidth = buttonWidth - arrowWidth - m_padding;
if (leftToRight) {
- textLeft += widthModifier;
+ textRect = QRect(m_padding, 0, textRectWidth, buttonHeight);
+ } else {
+ // If no separator is drawn, we can start writing text from 0
+ textRect = QRect(m_drawSeparator ? arrowWidth : 0, 0, textRectWidth, buttonHeight);
}
- textWidth -= widthModifier;
+ drawHoverBackground(&painter);
+
+ // Draw gradient overlay if text is clipped
painter.setPen(fgColor);
const bool clipped = isTextClipped();
- QRect textRect(textLeft, 0, textWidth, buttonHeight);
if (clipped) {
QColor bgColor = fgColor;
bgColor.setAlpha(0);
painter.setPen(pen);
}
+ // Draw folder name
int textFlags = Qt::AlignVCenter;
-
- if (leftToRight) {
- textRect.setLeft(textRect.left() + m_padding / 2);
- } else {
- textRect.setRight(textRect.right() - m_padding / 2);
- }
-
if (m_showMnemonic) {
textFlags |= Qt::TextShowMnemonic;
painter.drawText(textRect, textFlags, text());
painter.drawText(textRect, textFlags, plainText());
}
+ // Draw separator arrow
if (m_drawSeparator) {
QStyleOption option;
option.initFrom(this);
+ option.palette = palette();
+ option.palette.setColor(QPalette::Text, fgColor);
+ option.palette.setColor(QPalette::WindowText, fgColor);
+ option.palette.setColor(QPalette::ButtonText, fgColor);
+
if (leftToRight) {
- option.rect = QRect(rect().topRight(), rect().bottomRight());
+ option.rect = QRect(textRect.right(), 0, arrowWidth, buttonHeight);
} else {
- option.rect = QRect(rect().topLeft(), rect().bottomLeft());
+ // Separator is the first item in RtL mode
+ option.rect = QRect(0, 0, arrowWidth, buttonHeight);
}
- // Draw CE_Splitter instead of PE_IndicatorToolBarSeparator, since the latter
- // will be turned off if application style has separators turned off
- style()->drawControl(QStyle::CE_Splitter, &option, &painter, this);
+ if (!m_hoverOverArrow) {
+ option.state = QStyle::State_None;
+ }
+ style()->drawPrimitive(leftToRight ? QStyle::PE_IndicatorArrowRight : QStyle::PE_IndicatorArrowLeft, &option, &painter, this);
}
}
if (isTextClipped()) {
setToolTip(plainText());
}
+ if (!m_hoverOverButton) {
+ m_hoverOverButton = true;
+ update();
+ }
}
void KUrlNavigatorButton::leaveEvent(QEvent *event)
KUrlNavigatorButtonBase::leaveEvent(event);
setToolTip(QString());
- if (m_hoverOverIcon) {
- m_hoverOverIcon = false;
+ if (m_hoverOverArrow) {
+ m_hoverOverArrow = false;
+ update();
+ }
+ if (m_hoverOverButton) {
+ m_hoverOverButton = false;
update();
}
}
void KUrlNavigatorButton::dragMoveEvent(QDragMoveEvent *event)
{
QRect rect = event->answerRect();
- if (isAboveIcon(rect.center().x())) {
- m_hoverOverIcon = true;
+
+ if (isAboveSeparator(rect.center().x())) {
+ m_hoverOverArrow = true;
update();
if (m_subDirsMenu == nullptr) {
m_subDirsMenu->deleteLater();
m_subDirsMenu = nullptr;
}
- m_hoverOverIcon = false;
+ m_hoverOverArrow = false;
update();
}
}
{
KUrlNavigatorButtonBase::dragLeaveEvent(event);
- m_hoverOverIcon = false;
+ m_hoverOverArrow = false;
setDisplayHintEnabled(DraggedHint, false);
update();
}
void KUrlNavigatorButton::mousePressEvent(QMouseEvent *event)
{
- if (isAboveIcon(qRound(event->position().x())) && (event->button() == Qt::LeftButton)) {
+ if (isAboveSeparator(qRound(event->position().x())) && (event->button() == Qt::LeftButton)) {
// the mouse is pressed above the folder button
startSubDirsJob();
}
void KUrlNavigatorButton::mouseReleaseEvent(QMouseEvent *event)
{
- if (!isAboveIcon(qRound(event->position().x())) || (event->button() != Qt::LeftButton)) {
+ if (!isAboveSeparator(qRound(event->position().x())) || (event->button() != Qt::LeftButton)) {
// the mouse has been released above the text area and not
// above the folder button
Q_EMIT navigatorButtonActivated(m_url, event->button(), event->modifiers());
{
KUrlNavigatorButtonBase::mouseMoveEvent(event);
- const bool hoverOverIcon = isAboveIcon(qRound(event->position().x()));
- if (hoverOverIcon != m_hoverOverIcon) {
- m_hoverOverIcon = hoverOverIcon;
+ const bool hoverOverIcon = isAboveSeparator(qRound(event->position().x()));
+ if (hoverOverIcon != m_hoverOverArrow) {
+ m_hoverOverArrow = hoverOverIcon;
update();
}
}
initMenu(m_subDirsMenu, 0);
const bool leftToRight = (layoutDirection() == Qt::LeftToRight);
- const int popupX = !leftToRight ? width() - iconWidth() : 0;
+ const int popupX = leftToRight ? width() - arrowWidth() : 0;
const QPoint popupPos = parentWidget()->mapToGlobal(geometry().bottomLeft() + QPoint(popupX, 0));
QPointer<QObject> guard(this);
return dest;
}
-int KUrlNavigatorButton::iconWidth() const
+int KUrlNavigatorButton::arrowWidth() const
+{
+ // if there isn't arrow then return 0
+ int width = 0;
+ if (!m_subDir.isEmpty()) {
+ width = height() / 2;
+ if (width < 4) {
+ width = 4;
+ }
+ }
+
+ return width;
+}
+
+int KUrlNavigatorButton::textWidth() const
{
- return iconSize().width() * devicePixelRatioF();
+ QFont adjustedFont(font());
+ adjustedFont.setBold(m_subDir.isEmpty());
+ return QFontMetrics(adjustedFont).size(Qt::TextSingleLine, plainText()).width();
}
-bool KUrlNavigatorButton::isAboveIcon(int x) const
+bool KUrlNavigatorButton::isAboveSeparator(int x) const
{
const bool leftToRight = (layoutDirection() == Qt::LeftToRight);
- return !leftToRight ? (x >= width() - iconWidth() - m_padding) : (x < iconWidth() + m_padding);
+ return leftToRight ? (x >= width() - arrowWidth()) : (x < arrowWidth() + m_padding);
}
bool KUrlNavigatorButton::isTextClipped() const
{
// Ignore padding when resizing, so text doesnt go under it
- int availableWidth = width() - m_padding;
- if (!m_subDir.isEmpty()) {
- availableWidth -= iconWidth();
- }
+ int availableWidth = width() - arrowWidth() - m_padding;
- QFont adjustedFont(font());
- adjustedFont.setBold(m_subDir.isEmpty());
- return QFontMetrics(adjustedFont).size(Qt::TextSingleLine, plainText()).width() >= availableWidth;
+ return textWidth() >= availableWidth;
}
void KUrlNavigatorButton::updateMinimumWidth()
const int oldMinWidth = minimumWidth();
int minWidth = sizeHint().width();
- if (minWidth < 40) {
- minWidth = 40;
+ if (minWidth < 10) {
+ minWidth = 10;
} else if (minWidth > 150) {
// don't let an overlong path name waste all the URL navigator space
minWidth = 150;