25#include <tqapplication.h>
27#include <tqdatetime.h>
36#include <tdeapplication.h>
37#include <kdecorationfactory.h>
43#include "kcommondecoration.h"
44#include "kcommondecoration.moc"
46KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
57KCommonDecoration::~KCommonDecoration()
59 for (
int n=0; n<NumButtons; n++) {
60 if (m_button[n])
delete m_button[n];
62 delete m_previewWidget;
88 case LM_TitleEdgeBottom:
89 case LM_TitleEdgeLeft:
90 case LM_TitleEdgeRight:
91 case LM_TitleBorderLeft:
92 case LM_TitleBorderRight:
101 case LM_ButtonSpacing:
104 case LM_ButtonMarginTop:
105 case LM_RightButtonsMarginTop:
108 case LM_ExplicitButtonSpacer:
121 widget()->setBackgroundMode(NoBackground);
123 widget()->installEventFilter(
this );
127 connect(
this, TQ_SIGNAL(
keepAboveChanged(
bool) ), TQ_SLOT(keepAboveChange(
bool) ) );
128 connect(
this, TQ_SIGNAL(
keepBelowChanged(
bool) ), TQ_SLOT(keepBelowChange(
bool) ) );
166 TQRect r =
widget()->rect();
167 int r_x, r_y, r_x2, r_y2;
168 r.coords(&r_x, &r_y, &r_x2, &r_y2);
171 if (m_previewWidget) {
177 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
179 int left = r_x+borderLeft;
180 int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
181 int width = r_x2-borderRight-left+1;
182 int height = r_y2-borderBottom-top+1;
183 m_previewWidget->setGeometry(left, top,
width,
height);
184 moveWidget(left,top, m_previewWidget);
189 for (
int n=0; n<NumButtons; n++) {
191 TQSize newSize = TQSize(
layoutMetric(LM_ButtonWidth,
true, m_button[n]),
193 if (newSize != m_button[n]->size() )
194 m_button[n]->setSize(newSize);
200 if (m_buttonsLeft.count() > 0) {
201 const int buttonSpacing =
layoutMetric(LM_ButtonSpacing);
203 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
204 bool elementLayouted =
false;
206 if (!(*it)->isHidden() ) {
207 moveWidget(x,y, *it);
208 x +=
layoutMetric(LM_ButtonWidth,
true, ::tqt_cast<KCommonDecorationButton*>(*it) );
209 elementLayouted =
true;
213 elementLayouted =
true;
215 if (elementLayouted && it != m_buttonsLeft.end() )
220 if (m_buttonsRight.count() > 0) {
222 const int titleEdgeRightLeft = r_x2-
layoutMetric(LM_TitleEdgeRight)+1;
224 const int buttonSpacing =
layoutMetric(LM_ButtonSpacing);
225 int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
226 for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
227 bool elementLayouted =
false;
229 if (!(*it)->isHidden() ) {
230 moveWidget(x,y, *it);
231 x +=
layoutMetric(LM_ButtonWidth,
true, ::tqt_cast<KCommonDecorationButton*>(*it) );;
232 elementLayouted =
true;
236 elementLayouted =
true;
238 if (elementLayouted && it != m_buttonsRight.end() )
246 for (
int n=0; n<NumButtons; n++)
247 if (m_button[n]) m_button[n]->update();
252 for (
int n=0; n<NumButtons; n++)
256void KCommonDecoration::resetLayout()
258 for (
int n=0; n<NumButtons; n++) {
264 m_buttonsLeft.clear();
265 m_buttonsRight.clear();
267 delete m_previewWidget;
272 m_previewWidget =
new TQLabel(i18n(
"%1 is the name of window decoration style",
"<center><b>%1 preview</b></center>").arg(
visibleName() ),
widget());
273 m_previewWidget->show();
276 addButtons(m_buttonsLeft,
279 addButtons(m_buttonsRight,
285 const int minTitleBarWidth = 35;
286 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,
true) + buttonContainerWidth(m_buttonsRight,
true) +
290 btnHideLastWidth = 0;
293int KCommonDecoration::buttonsLeftWidth()
const
295 return buttonContainerWidth(m_buttonsLeft);
298int KCommonDecoration::buttonsRightWidth()
const
300 return buttonContainerWidth(m_buttonsRight);
303int KCommonDecoration::buttonContainerWidth(
const ButtonContainer &btnContainer,
bool countHidden)
const
305 int explicitSpacer =
layoutMetric(LM_ExplicitButtonSpacer);
307 int shownElementsCount = 0;
310 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
312 if (countHidden || !(*it)->isHidden() ) {
314 ++shownElementsCount;
318 ++shownElementsCount;
321 w +=
layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
326bool KCommonDecoration::isModalSystemNotification()
328 unsigned char *data = 0;
331 unsigned long n, left;
332 Atom kde_wm_system_modal_notification;
333 kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(),
"_TDE_WM_MODAL_SYS_NOTIFICATION", False);
334 result = XGetWindowProperty(tqt_xdisplay(),
windowId(), kde_wm_system_modal_notification, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data);
335 if (result == Success && data != None && format == 32 )
342void KCommonDecoration::addButtons(ButtonContainer &btnContainer,
const TQString& s,
bool isLeft)
344 if (s.length() > 0) {
345 for (
unsigned n=0; n < s.length(); n++) {
346 KCommonDecorationButton *btn = 0;
349 if (!isModalSystemNotification()) {
350 if (!m_button[MenuButton]){
355 connect(btn, TQ_SIGNAL(pressed()), TQ_SLOT(menuButtonPressed()));
356 connect(btn, TQ_SIGNAL(released()),
this, TQ_SLOT(menuButtonReleased()));
358 m_button[MenuButton] = btn;
363 if (!isModalSystemNotification()) {
364 if (!m_button[OnAllDesktopsButton]){
368 btn->
setTipText(oad?i18n(
"Not on all desktops"):i18n(
"On all desktops") );
369 btn->setToggleButton(
true);
373 m_button[OnAllDesktopsButton] = btn;
384 m_button[HelpButton] = btn;
392 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(
minimize()));
394 m_button[MinButton] = btn;
403 btn->
setTipText(max?i18n(
"Restore"):i18n(
"Maximize") );
404 btn->setToggleButton(
true);
406 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotMaximize()));
408 m_button[MaxButton] = btn;
416 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(
closeWindow()));
418 m_button[CloseButton] = btn;
422 if (!m_button[AboveButton]){
426 btn->
setTipText(above?i18n(
"Do not keep above others"):i18n(
"Keep above others") );
427 btn->setToggleButton(
true);
429 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotKeepAbove()));
431 m_button[AboveButton] = btn;
435 if (!m_button[BelowButton]){
439 btn->
setTipText(below?i18n(
"Do not keep below others"):i18n(
"Keep below others") );
440 btn->setToggleButton(
true);
442 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotKeepBelow()));
444 m_button[BelowButton] = btn;
452 btn->
setTipText(shaded?i18n(
"Unshade"):i18n(
"Shade") );
453 btn->setToggleButton(
true);
454 btn->setOn( shaded );
455 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotShade()));
457 m_button[ShadeButton] = btn;
461 btnContainer.append(0);
466 btn->setLeft(isLeft);
469 btnContainer.append(btn);
476void KCommonDecoration::calcHiddenButtons()
478 if (
width() == btnHideLastWidth)
481 btnHideLastWidth =
width();
484 KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
485 m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
486 m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
487 const int buttonsCount =
sizeof( btnArray ) /
sizeof( btnArray[ 0 ] );
489 int current_width =
width();
493 while (current_width < btnHideMinWidth && count < buttonsCount)
495 if (btnArray[count] ) {
496 current_width += btnArray[count]->width();
497 if (btnArray[count]->isVisible() )
498 btnArray[count]->hide();
503 for(
int i = count; i < buttonsCount; i++)
507 if (! btnArray[i]->isHidden() )
515void KCommonDecoration::show()
532 return TQSize(minWidth,
540 if( m_button[MaxButton] ) {
553 if ( m_button[OnAllDesktopsButton] ) {
556 i18n(
"Not on all desktops")
557 : i18n(
"On all desktops"));
564 if ( m_button[ShadeButton] ) {
566 m_button[ShadeButton]->setOn( shaded );
567 m_button[ShadeButton]->setTipText( shaded ?
576 if (m_button[MenuButton])
578 m_button[MenuButton]->update();
594void KCommonDecoration::keepAboveChange(
bool above)
596 if (m_button[AboveButton])
598 m_button[AboveButton]->setOn(above);
599 m_button[AboveButton]->
setTipText( above?i18n(
"Do not keep above others"):i18n(
"Keep above others") );
603 if (m_button[BelowButton] && m_button[BelowButton]->isOn())
605 m_button[BelowButton]->setOn(
false);
606 m_button[BelowButton]->setTipText( i18n(
"Keep below others") );
611void KCommonDecoration::keepBelowChange(
bool below)
613 if (m_button[BelowButton])
615 m_button[BelowButton]->setOn(below);
616 m_button[BelowButton]->setTipText( below?i18n(
"Do not keep below others"):i18n(
"Keep below others") );
620 if (m_button[AboveButton] && m_button[AboveButton]->isOn())
622 m_button[AboveButton]->setOn(
false);
623 m_button[AboveButton]->setTipText( i18n(
"Keep above others") );
628void KCommonDecoration::slotMaximize()
630 if (m_button[MaxButton])
632 maximize(m_button[MaxButton]->lastMousePress() );
636void KCommonDecoration::slotShade()
641void KCommonDecoration::slotKeepAbove()
646void KCommonDecoration::slotKeepBelow()
651void KCommonDecoration::menuButtonPressed()
653 static TQTime* t = NULL;
654 static KCommonDecoration* lastClient = NULL;
657 bool dbl = (lastClient==
this && t->elapsed() <= TQApplication::doubleClickInterval());
661 TQRect menuRect = m_button[MenuButton]->rect();
662 TQPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
663 TQPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+TQPoint(0,2);
664 KDecorationFactory* f =
factory();
666 if( !f->exists(
this ))
668 m_button[MenuButton]->setDown(
false);
674void KCommonDecoration::menuButtonReleased()
680void KCommonDecoration::resizeEvent(TQResizeEvent *)
693void KCommonDecoration::moveWidget(
int x,
int y, TQWidget *widget)
const
695 TQPoint p =
widget->pos();
699 if (x!=oldX || y!=oldY)
703void KCommonDecoration::resizeWidget(
int w,
int h, TQWidget *widget)
const
705 TQSize s =
widget->size();
706 int oldW = s.width();
707 int oldH = s.height();
709 if (w!=oldW || h!=oldH)
713void KCommonDecoration::mouseDoubleClickEvent(TQMouseEvent *e)
715 if( e->button() != TQt::LeftButton )
725void KCommonDecoration::wheelEvent(TQWheelEvent *e)
743 const char *q4dpistr=getenv(
"Q4DPI");
744 int q4dpi=q4dpistr ? atoi(q4dpistr) : 0;
745 if(q4dpi>10 && q4dpi<2000)
746 q4CornerBase=(18*q4dpi)/96;
748 const int corner = q4CornerBase+3*
layoutMetric(LM_BorderBottom,
false)/2;
751 TQRect r =
widget()->rect();
752 int r_x, r_y, r_x2, r_y2;
753 r.coords(&r_x, &r_y, &r_x2, &r_y2);
761 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
762 const int titleEdgeLeft =
layoutMetric(LM_TitleEdgeLeft);
763 const int titleEdgeRight =
layoutMetric(LM_TitleEdgeRight);
765 const int borderBottomTop = r_y2-borderBottom+1;
766 const int borderLeftRight = r_x+borderLeft-1;
768 const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
769 const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
770 const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
771 const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
773 if (p_y <= titleEdgeTopBottom) {
774 if (p_x <= r_x+corner)
775 pos = PositionTopLeft;
776 else if (p_x >= r_x2-corner)
777 pos = PositionTopRight;
780 }
else if (p_y <= titleEdgeBottomBottom) {
781 if (p_x <= titleEdgeLeftRight)
782 pos = PositionTopLeft;
783 else if (p_x >= titleEdgeRightLeft)
784 pos = PositionTopRight;
786 pos = PositionCenter;
787 }
else if (p_y < borderBottomTop) {
788 if (p_y < r_y2-corner) {
789 if (p_x <= borderLeftRight)
794 if (p_x <= borderLeftRight)
795 pos = PositionBottomLeft;
797 pos = PositionBottomRight;
799 }
else if(p_y >= borderBottomTop) {
800 if (p_x <= r_x+corner)
801 pos = PositionBottomLeft;
802 else if (p_x >= r_x2-corner)
803 pos = PositionBottomRight;
805 pos = PositionBottom;
817 int w =
widget()->width();
818 int h =
widget()->height();
820 bool tl=
true,tr=
true,bl=
true,br=
true;
822 TQDesktopWidget *
desktop=TDEApplication::desktop();
824 for(
int screen=0; screen <
desktop->numScreens(); ++screen)
826 TQRect fullscreen(
desktop->screenGeometry(screen));
829 if(window.topLeft() == fullscreen.topLeft() ) tl =
false;
830 if(window.topRight() == fullscreen.topRight() ) tr =
false;
831 if(window.bottomLeft() == fullscreen.bottomLeft() ) bl =
false;
832 if(window.bottomRight()== fullscreen.bottomRight() ) br =
false;
835 TQRegion mask(0, 0, w, h);
861bool KCommonDecoration::eventFilter( TQObject* o, TQEvent* e )
867 case TQEvent::Resize:
868 resizeEvent(
static_cast<TQResizeEvent*
>(e) );
873 case TQEvent::MouseButtonDblClick:
874 mouseDoubleClickEvent(
static_cast<TQMouseEvent*
>( e ));
876 case TQEvent::MouseButtonPress:
880 wheelEvent(
static_cast<TQWheelEvent*
>( e ));
887const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
888 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::TopMenuMask
889 | NET::UtilityMask | NET::SplashMask;
893 NET::WindowType type =
windowType( SUPPORTED_WINDOW_TYPES_MASK );
894 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
899 int r_x, r_y, r_x2, r_y2;
900 widget()->rect().coords(&r_x, &r_y, &r_x2, &r_y2);
901 const int titleEdgeLeft =
layoutMetric(LM_TitleEdgeLeft);
903 const int titleEdgeRight =
layoutMetric(LM_TitleEdgeRight);
904 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
905 const int titleBorderLeft =
layoutMetric(LM_TitleBorderLeft);
906 const int titleBorderRight =
layoutMetric(LM_TitleBorderRight);
908 const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
909 return TQRect(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft, r_y+titleEdgeTop,
910 r_x2-titleEdgeRight-buttonsRightWidth()-titleBorderRight-(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft),
911 titleEdgeBottomBottom-(r_y+titleEdgeTop) );
915KCommonDecorationButton::KCommonDecorationButton(ButtonType type,
KCommonDecoration *parent,
const char *name)
916 : TQButton(parent->widget(), name),
917 m_decoration(parent),
919 m_realizeButtons(TQt::LeftButton),
920 m_lastMouse(TQt::NoButton),
923 setCursor(ArrowCursor);
926KCommonDecorationButton::~KCommonDecorationButton()
945void KCommonDecorationButton::setLeft(
bool left)
952 m_realizeButtons = btns;
957 if (!m_size.isValid() || s != size() ) {
960 setFixedSize(m_size);
965TQSize KCommonDecorationButton::sizeHint()
const
971 TQToolTip::remove(
this );
972 TQToolTip::add(
this, tip );
975void KCommonDecorationButton::setToggleButton(
bool toggle)
977 TQButton::setToggleButton(toggle);
981void KCommonDecorationButton::setOn(
bool on)
989void KCommonDecorationButton::mousePressEvent(TQMouseEvent* e)
991 m_lastMouse = e->button();
993 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
994 (e->button()&m_realizeButtons)?TQt::LeftButton:TQt::NoButton, e->state());
996 TQButton::mousePressEvent(&me);
999void KCommonDecorationButton::mouseReleaseEvent(TQMouseEvent* e)
1001 m_lastMouse = e->button();
1003 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
1004 (e->button()&m_realizeButtons)?TQt::LeftButton:TQt::NoButton, e->state());
1006 TQButton::mouseReleaseEvent(&me);
This class eases development of decorations by implementing parts of KDecoration which are error pron...
virtual void borders(int &left, int &right, int &top, int &bottom) const
This function should return the distance from each window side to the inner window.
virtual TQRegion cornerShape(WindowCorner corner)
virtual void maximizeChange()
This function is called whenever the maximalization state of the window changes.
virtual TQString defaultButtonsRight() const =0
The default title button order on the left.
virtual bool decorationBehaviour(DecorationBehaviour behaviour) const
This controls whether some specific behaviour should be enabled or not.
virtual KCommonDecorationButton * createButton(ButtonType type)=0
Create a new title bar button.
virtual TQString visibleName() const =0
The name of the decoration used in the decoration preview.
void updateButtons() const
Makes sure all buttons are repainted.
virtual TQSize minimumSize() const
This function should return the minimum required size for the decoration.
virtual void activeChange()
This function is called whenever the window either becomes or stops being active.
virtual void paintEvent(TQPaintEvent *e)=0
Draw the window decoration.
@ DB_ButtonHide
Hide buttons when there is not enough space in the titlebar.
@ DB_WindowMask
Set a mask on the window.
@ DB_MenuClose
Close window on double clicking the menu.
virtual void init()
Handles widget and layout creation, call the base implementation when subclassing this member.
virtual TQString defaultButtonsLeft() const =0
The default title button order on the left.
virtual void shadeChange()
This function is called whenever the window is shaded or unshaded.
TQRect titleRect() const
Convenience method.
bool isToolWindow() const
Convenience method.
LayoutMetric
Used to calculate the decoration layout.
virtual void iconChange()
This function is called whenever the window icon changes.
virtual void updateCaption()
This is used to update the painting of the title bar after the caption has been changed.
virtual void updateWindowShape()
This updates the window mask using the information provided by cornerShape().
virtual void captionChange()
This function is called whenever the caption changes.
virtual void reset(unsigned long changed)
Handles SettingButtons, call the base implementation when subclassing this member.
virtual void resize(const TQSize &s)
This method is called by twin when the style should resize the decoration window.
virtual int layoutMetric(LayoutMetric lm, bool respectWindowState=true, const KCommonDecorationButton *button=0) const
This controls the layout of the decoration in various ways.
void updateLayout() const
TODO: remove?
virtual void desktopChange()
This function is called whenever the desktop for the window changes.
void resetButtons() const
Manually call reset() on each button.
virtual Position mousePosition(const TQPoint &point) const
This function should return mouse cursor position in the decoration.
Position
These values represent positions inside an area.
@ SettingButtons
The button layout was changed.
@ MaximizeFull
Equal to MaximizeVertical | MaximizeHorizontal.
This is the base class for a decoration object.
void processMousePressEvent(TQMouseEvent *e)
This function is the default handler for mouse events.
static const KDecorationOptions * options()
Returns the KDecorationOptions object, which is used to access configuration settings for the decorat...
bool isMinimizable() const
Returns true if the decorated window can be minimized by the user.
void closeWindow()
This function can be called by the decoration to request closing of the decorated window.
void setShade(bool set)
Shades or unshades the decorated window.
MaximizeMode maximizeMode() const
Returns the current maximization mode of the decorated window.
bool keepAbove() const
Returns true if the decorated window should be kept above other windows.
bool isPreview() const
If this function returns true, the decorated window is used as a preview e.g.
bool isShadeable() const
Returns true if the decorated window can be shaded.
bool isSetShade() const
Returns true if the decorated window was set to be shaded.
void showWindowMenu(const TQRect &pos)
This function invokes the window operations menu.
bool keepBelow() const
Returns true if the decorated window should be kept below other windows.
TQRect geometry() const
Returns the geometry of the decoration.
WId windowId() const
Returns the handle of the window that is being decorated.
void showContextHelp()
Start showing context help in the window (i.e.
bool isMaximizable() const
Returns true if the decorated window can be maximized.
int height() const
Convenience function that returns the height of the decoration.
TQWidget * widget()
Returns the main widget for the decoration.
void setKeepAbove(bool set)
Sets or reset keeping this window above others.
void createMainWidget(TQt::WFlags flags=0)
Convenience functions that creates and sets a main widget as necessary.
KDecorationFactory * factory() const
Returns the factory that created this decoration.
void setKeepBelow(bool set)
Sets or reset keeping this window below others.
void minimize()
Minimize the decorated window.
void titlebarDblClickOperation()
This function performs the operation configured as titlebar double click operation.
bool providesContextHelp() const
Return true if the decorated window can show context help (i.e.
int desktop() const
Returns the number of the virtual desktop the decorated window is currently on (including NET::OnAllD...
bool isCloseable() const
Returns true if the decoration window can be closed by the user.
void keepBelowChanged(bool)
This signal is emitted whenever the window's keep-below state changes.
void keepAboveChanged(bool)
This signal is emitted whenever the window's keep-above state changes.
bool isOnAllDesktops() const
Convenience function that returns true if the window is on all virtual desktops.
void setMask(const TQRegion ®, int mode=0)
If the decoration is non-rectangular, this function needs to be called to set the shape of the decora...
void titlebarMouseWheelOperation(int delta)
This function performs the operation configured as titlebar wheel mouse operation.
void toggleOnAllDesktops()
This function toggles the on-all-desktops state of the decorated window.
NET::WindowType windowType(unsigned long supported_types) const
This function returns the window type of the decorated window.
int width() const
Convenience function that returns the width of the decoration.