From f1ad43864fd8eb4a443fb2f355eff5341b6e99ff Mon Sep 17 00:00:00 2001 From: Sandro Giessl Date: Mon, 21 Mar 2005 15:47:39 +0000 Subject: [PATCH] - Add KCommonDecoration::isLeft() for Quartz. - Hide buttons one by another when the window size shrinks below a certain width. Implemented so that Quartz doesn't use any functionality, but it's quite useful in other decos, too -> enabled by default. Minimum size calculation still needs some tweaking... svn path=/trunk/kdebase/kwin/; revision=399463 --- lib/kcommondecoration.cpp | 97 ++++++++++++++++++++++++++++++++++----- lib/kcommondecoration.h | 14 +++++- 2 files changed, 97 insertions(+), 14 deletions(-) diff --git a/lib/kcommondecoration.cpp b/lib/kcommondecoration.cpp index 9669b75969..d1e053c48c 100644 --- a/lib/kcommondecoration.cpp +++ b/lib/kcommondecoration.cpp @@ -63,6 +63,9 @@ bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const case DB_WindowMask: return false; + + case DB_ButtonHide: + return true; } return false; @@ -156,13 +159,18 @@ void KCommonDecoration::updateLayout() const int y = r_y + layoutMetric(LM_TitleEdgeTop); int x = r_x + layoutMetric(LM_TitleEdgeLeft); for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) { + bool elementLayouted = false; if (*it) { - moveWidget(x,y, *it); - x += layoutMetric(LM_ButtonWidth, true, ::qt_cast(*it) ); + if (!(*it)->isHidden() ) { + moveWidget(x,y, *it); + x += layoutMetric(LM_ButtonWidth, true, ::qt_cast(*it) ); + elementLayouted = true; + } } else { x+= layoutMetric(LM_ExplicitButtonSpacer); + elementLayouted = true; } - if (it != m_buttonsLeft.end() ) + if (elementLayouted && it != m_buttonsLeft.end() ) x += buttonSpacing; } } @@ -174,14 +182,18 @@ void KCommonDecoration::updateLayout() const int y = r_y + layoutMetric(LM_TitleEdgeTop); int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight); for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) { + bool elementLayouted = false; if (*it) { - int buttonWidth = layoutMetric(LM_ButtonWidth, true, ::qt_cast(*it) ); - moveWidget(x,y, *it); - x += buttonWidth; + if (!(*it)->isHidden() ) { + moveWidget(x,y, *it); + x += layoutMetric(LM_ButtonWidth, true, ::qt_cast(*it) );; + elementLayouted = true; + } } else { x += layoutMetric(LM_ExplicitButtonSpacer); + elementLayouted = true; } - if (it != m_buttonsRight.end() ) + if (elementLayouted && it != m_buttonsRight.end() ) x += buttonSpacing; } } @@ -220,9 +232,11 @@ void KCommonDecoration::resetLayout() } addButtons(m_buttonsLeft, - options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft() ); + options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(), + true); addButtons(m_buttonsRight, - options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight() ); + options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(), + false); updateLayout(); } @@ -241,20 +255,26 @@ int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer) { int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer); + int shownElementsCount = 0; + int w = 0; for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) { if (*it) { - w += (*it)->width(); + if (!(*it)->isHidden() ) { + w += (*it)->width(); + ++shownElementsCount; + } } else { w += explicitSpacer; + ++shownElementsCount; } } - w += layoutMetric(LM_ButtonSpacing)*(btnContainer.count()-1); + w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1); return w; } -void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s) +void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft) { if (s.length() > 0) { for (unsigned n=0; n < s.length(); n++) { @@ -374,6 +394,7 @@ void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& if (btn) { + btn->setLeft(isLeft); btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) ); btn->show(); btnContainer.append(btn); @@ -383,8 +404,47 @@ void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& } } +void KCommonDecoration::calcHiddenButtons() +{ + //Hide buttons in this order: + //Shade, Below, Above, OnAllDesktops, Help, Maximize, Menu, Minimize, Close. + KCommonDecorationButton* btnArray[] = { m_button[ShadeButton], m_button[BelowButton], m_button[AboveButton], + m_button[OnAllDesktopsButton], m_button[HelpButton], m_button[MaxButton], + m_button[MenuButton], m_button[MinButton], m_button[CloseButton] }; + const int buttonsCount = sizeof( btnArray ) / sizeof( btnArray[ 0 ] ); + + int minwidth = 160; // TODO: calculate a better value taking the button width into account... + int current_width = width(); + int count = 0; + int i; + + // Find out how many buttons we have to hide. + while (current_width < minwidth && count < buttonsCount) + { + if (btnArray[count] ) + current_width += btnArray[count]->width(); + count++; + } + + // Hide the required buttons... + for(i = 0; i < count; i++) + { + if (btnArray[i] && btnArray[i]->isVisible() ) + btnArray[i]->hide(); + } + + // Show the rest of the buttons... + for(i = count; i < buttonsCount; i++) + { + if (btnArray[i] && (!btnArray[i]->isVisible()) ) + btnArray[i]->show(); + } +} + void KCommonDecoration::show() { + if (decorationBehaviour(DB_ButtonHide) ) + calcHiddenButtons(); widget()->show(); } @@ -541,6 +601,9 @@ void KCommonDecoration::menuButtonReleased() void KCommonDecoration::resizeEvent(QResizeEvent */*e*/) { + if (decorationBehaviour(DB_ButtonHide) ) + calcHiddenButtons(); + updateLayout(); updateWindowShape(); @@ -752,6 +815,16 @@ ButtonType KCommonDecorationButton::type() return m_type;; } +bool KCommonDecorationButton::isLeft() +{ + return m_isLeft; +} + +void KCommonDecorationButton::setLeft(bool left) +{ + m_isLeft = left; +} + void KCommonDecorationButton::setRealizeButtons(int btns) { m_realizeButtons = btns; diff --git a/lib/kcommondecoration.h b/lib/kcommondecoration.h index a3c3c736e0..5135048ec9 100644 --- a/lib/kcommondecoration.h +++ b/lib/kcommondecoration.h @@ -116,7 +116,8 @@ class KWIN_EXPORT KCommonDecoration : public KDecoration enum DecorationBehaviour { DB_MenuClose, ///< Close window on double clicking the menu - DB_WindowMask ///< Set a mask on the window + DB_WindowMask, ///< Set a mask on the window + DB_ButtonHide ///< Hide buttons when there is not enough space in the titlebar }; enum WindowCorner @@ -255,7 +256,8 @@ class KWIN_EXPORT KCommonDecoration : public KDecoration typedef QValueVector ButtonContainer; ///< If the entry is 0, it's a spacer. int buttonContainerWidth(const ButtonContainer &btnContainer) const; - void addButtons(ButtonContainer &btnContainer, const QString& buttons); + void addButtons(ButtonContainer &btnContainer, const QString& buttons, bool isLeft); + void calcHiddenButtons(); KCommonDecorationButton *m_button[NumButtons]; @@ -306,6 +308,11 @@ class KWIN_EXPORT KCommonDecorationButton : public QButton */ ButtonType type(); + /** + * Whether the button is left of the titlebar or not. + */ + bool isLeft(); + /** * Set which mouse buttons the button should honor. Used e.g. to prevent accidental right mouse clicks. */ @@ -328,6 +335,7 @@ class KWIN_EXPORT KCommonDecorationButton : public QButton protected: void setToggleButton(bool toggle); void setOn(bool on); + void setLeft(bool left); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); @@ -338,6 +346,8 @@ class KWIN_EXPORT KCommonDecorationButton : public QButton QSize m_size; ButtonState m_lastMouse; + bool m_isLeft; + KCommonDecorationButtonPrivate *d; };