• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • twin/lib
 

twin/lib

  • twin
  • lib
kcommondecoration.cpp
1/*
2 This file is part of the KDE project.
3
4 Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24
25#include <tqapplication.h>
26#include <tqcursor.h>
27#include <tqdatetime.h>
28#include <tqlabel.h>
29#include <tqtooltip.h>
30#include <tqwidget.h>
31
32#include <stdlib.h>
33
34#include <kdebug.h>
35
36#include <tdeapplication.h>
37#include <kdecorationfactory.h>
38#include <tdelocale.h>
39
40#include <X11/Xlib.h>
41#include <X11/Xatom.h>
42
43#include "kcommondecoration.h"
44#include "kcommondecoration.moc"
45
46KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
47 : KDecoration (bridge, factory),
48 m_previewWidget(0),
49 btnHideMinWidth(200),
50 btnHideLastWidth(0),
51 closing(false)
52{
53 // sizeof(...) is calculated at compile time
54 memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
55}
56
57KCommonDecoration::~KCommonDecoration()
58{
59 for (int n=0; n<NumButtons; n++) {
60 if (m_button[n]) delete m_button[n];
61 }
62 delete m_previewWidget;
63}
64
65bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const
66{
67 switch (behaviour) {
68 case DB_MenuClose:
69 return false;
70
71 case DB_WindowMask:
72 return false;
73
74 case DB_ButtonHide:
75 return true;
76 }
77
78 return false;
79}
80
81int KCommonDecoration::layoutMetric(LayoutMetric lm, bool, const KCommonDecorationButton *) const
82{
83 switch (lm) {
84 case LM_BorderLeft:
85 case LM_BorderRight:
86 case LM_BorderBottom:
87 case LM_TitleEdgeTop:
88 case LM_TitleEdgeBottom:
89 case LM_TitleEdgeLeft:
90 case LM_TitleEdgeRight:
91 case LM_TitleBorderLeft:
92 case LM_TitleBorderRight:
93 return 5;
94
95
96 case LM_ButtonWidth:
97 case LM_ButtonHeight:
98 case LM_TitleHeight:
99 return 20;
100
101 case LM_ButtonSpacing:
102 return 5;
103
104 case LM_ButtonMarginTop:
105 case LM_RightButtonsMarginTop:
106 return 0;
107
108 case LM_ExplicitButtonSpacer:
109 return 5;
110
111 default:
112 return 0;
113 }
114}
115
116void KCommonDecoration::init()
117{
118 createMainWidget(TQt::WNoAutoErase);
119
120 // for flicker-free redraws
121 widget()->setBackgroundMode(NoBackground);
122
123 widget()->installEventFilter( this );
124
125 resetLayout();
126
127 connect(this, TQ_SIGNAL(keepAboveChanged(bool) ), TQ_SLOT(keepAboveChange(bool) ) );
128 connect(this, TQ_SIGNAL(keepBelowChanged(bool) ), TQ_SLOT(keepBelowChange(bool) ) );
129
130 updateCaption();
131}
132
133void KCommonDecoration::reset( unsigned long changed )
134{
135 if (changed & SettingButtons) {
136 resetLayout();
137 widget()->update();
138 }
139}
140
141TQRegion KCommonDecoration::cornerShape(WindowCorner)
142{
143 return TQRegion();
144}
145
146void KCommonDecoration::updateCaption()
147{
148 // This should be reimplemented in decorations for better efficiency
149 widget()->update();
150}
151
152void KCommonDecoration::borders( int& left, int& right, int& top, int& bottom ) const
153{
154 left = layoutMetric(LM_BorderLeft);
155 right = layoutMetric(LM_BorderRight);
156 bottom = layoutMetric(LM_BorderBottom);
157 top = layoutMetric(LM_TitleHeight) +
158 layoutMetric(LM_TitleEdgeTop) +
159 layoutMetric(LM_TitleEdgeBottom);
160
161 updateLayout(); // TODO!! don't call everytime we are in ::borders
162}
163
164void KCommonDecoration::updateLayout() const
165{
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);
169
170 // layout preview widget
171 if (m_previewWidget) {
172 const int borderLeft = layoutMetric(LM_BorderLeft);
173 const int borderRight = layoutMetric(LM_BorderRight);
174 const int borderBottom = layoutMetric(LM_BorderBottom);
175 const int titleHeight = layoutMetric(LM_TitleHeight);
176 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
177 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
178
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);
185 resizeWidget(width, height, m_previewWidget);
186 }
187
188 // resize buttons...
189 for (int n=0; n<NumButtons; n++) {
190 if (m_button[n]) {
191 TQSize newSize = TQSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
192 layoutMetric(LM_ButtonHeight, true, m_button[n]) );
193 if (newSize != m_button[n]->size() )
194 m_button[n]->setSize(newSize);
195 }
196 }
197
198 // layout buttons
199 int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
200 if (m_buttonsLeft.count() > 0) {
201 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
202 int x = r_x + layoutMetric(LM_TitleEdgeLeft);
203 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
204 bool elementLayouted = false;
205 if (*it) {
206 if (!(*it)->isHidden() ) {
207 moveWidget(x,y, *it);
208 x += layoutMetric(LM_ButtonWidth, true, ::tqt_cast<KCommonDecorationButton*>(*it) );
209 elementLayouted = true;
210 }
211 } else {
212 x+= layoutMetric(LM_ExplicitButtonSpacer);
213 elementLayouted = true;
214 }
215 if (elementLayouted && it != m_buttonsLeft.end() )
216 x += buttonSpacing;
217 }
218 }
219
220 if (m_buttonsRight.count() > 0) {
221 int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop) + layoutMetric(LM_RightButtonsMarginTop);
222 const int titleEdgeRightLeft = r_x2-layoutMetric(LM_TitleEdgeRight)+1;
223
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;
228 if (*it) {
229 if (!(*it)->isHidden() ) {
230 moveWidget(x,y, *it);
231 x += layoutMetric(LM_ButtonWidth, true, ::tqt_cast<KCommonDecorationButton*>(*it) );;
232 elementLayouted = true;
233 }
234 } else {
235 x += layoutMetric(LM_ExplicitButtonSpacer);
236 elementLayouted = true;
237 }
238 if (elementLayouted && it != m_buttonsRight.end() )
239 x += buttonSpacing;
240 }
241 }
242}
243
244void KCommonDecoration::updateButtons() const
245{
246 for (int n=0; n<NumButtons; n++)
247 if (m_button[n]) m_button[n]->update();
248}
249
250void KCommonDecoration::resetButtons() const
251{
252 for (int n=0; n<NumButtons; n++)
253 if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
254}
255
256void KCommonDecoration::resetLayout()
257{
258 for (int n=0; n<NumButtons; n++) {
259 if (m_button[n]) {
260 delete m_button[n];
261 m_button[n] = 0;
262 }
263 }
264 m_buttonsLeft.clear();
265 m_buttonsRight.clear();
266
267 delete m_previewWidget;
268 m_previewWidget = 0;
269
270 // shown instead of the window contents in decoration previews
271 if(isPreview() ) {
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();
274 }
275
276 addButtons(m_buttonsLeft,
277 options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
278 true);
279 addButtons(m_buttonsRight,
280 options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
281 false);
282
283 updateLayout();
284
285 const int minTitleBarWidth = 35;
286 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,true) + buttonContainerWidth(m_buttonsRight,true) +
287 layoutMetric(LM_TitleEdgeLeft,false) + layoutMetric(LM_TitleEdgeRight,false) +
288 layoutMetric(LM_TitleBorderLeft,false) + layoutMetric(LM_TitleBorderRight,false) +
289 minTitleBarWidth;
290 btnHideLastWidth = 0;
291}
292
293int KCommonDecoration::buttonsLeftWidth() const
294{
295 return buttonContainerWidth(m_buttonsLeft);
296}
297
298int KCommonDecoration::buttonsRightWidth() const
299{
300 return buttonContainerWidth(m_buttonsRight);
301}
302
303int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
304{
305 int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
306
307 int shownElementsCount = 0;
308
309 int w = 0;
310 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
311 if (*it) {
312 if (countHidden || !(*it)->isHidden() ) {
313 w += (*it)->width();
314 ++shownElementsCount;
315 }
316 } else {
317 w += explicitSpacer;
318 ++shownElementsCount;
319 }
320 }
321 w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
322
323 return w;
324}
325
326bool KCommonDecoration::isModalSystemNotification()
327{
328 unsigned char *data = 0;
329 Atom actual;
330 int format, result;
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, /*(unsigned char **)*/ &data);
335 if (result == Success && data != None && format == 32 )
336 {
337 return true;
338 }
339 return false;
340}
341
342void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const TQString& s, bool isLeft)
343{
344 if (s.length() > 0) {
345 for (unsigned n=0; n < s.length(); n++) {
346 KCommonDecorationButton *btn = 0;
347 switch (s[n]) {
348 case 'M': // Menu button
349 if (!isModalSystemNotification()) {
350 if (!m_button[MenuButton]){
351 btn = createButton(MenuButton);
352 if (!btn) break;
353 btn->setTipText(i18n("Menu") );
354 btn->setRealizeButtons(TQt::LeftButton|TQt::RightButton);
355 connect(btn, TQ_SIGNAL(pressed()), TQ_SLOT(menuButtonPressed()));
356 connect(btn, TQ_SIGNAL(released()), this, TQ_SLOT(menuButtonReleased()));
357
358 m_button[MenuButton] = btn;
359 }
360 }
361 break;
362 case 'S': // OnAllDesktops button
363 if (!isModalSystemNotification()) {
364 if (!m_button[OnAllDesktopsButton]){
365 btn = createButton(OnAllDesktopsButton);
366 if (!btn) break;
367 const bool oad = isOnAllDesktops();
368 btn->setTipText(oad?i18n("Not on all desktops"):i18n("On all desktops") );
369 btn->setToggleButton(true);
370 btn->setOn( oad );
371 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(toggleOnAllDesktops()));
372
373 m_button[OnAllDesktopsButton] = btn;
374 }
375 }
376 break;
377 case 'H': // Help button
378 if ((!m_button[HelpButton]) && providesContextHelp()){
379 btn = createButton(HelpButton);
380 if (!btn) break;
381 btn->setTipText(i18n("Help") );
382 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(showContextHelp()));
383
384 m_button[HelpButton] = btn;
385 }
386 break;
387 case 'I': // Minimize button
388 if ((!m_button[MinButton]) && isMinimizable()){
389 btn = createButton(MinButton);
390 if (!btn) break;
391 btn->setTipText(i18n("Minimize") );
392 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(minimize()));
393
394 m_button[MinButton] = btn;
395 }
396 break;
397 case 'A': // Maximize button
398 if ((!m_button[MaxButton]) && isMaximizable()){
399 btn = createButton(MaxButton);
400 if (!btn) break;
401 btn->setRealizeButtons(TQt::LeftButton|TQt::MidButton|TQt::RightButton);
402 const bool max = maximizeMode()==MaximizeFull;
403 btn->setTipText(max?i18n("Restore"):i18n("Maximize") );
404 btn->setToggleButton(true);
405 btn->setOn( max );
406 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotMaximize()));
407
408 m_button[MaxButton] = btn;
409 }
410 break;
411 case 'X': // Close button
412 if ((!m_button[CloseButton]) && isCloseable()){
413 btn = createButton(CloseButton);
414 if (!btn) break;
415 btn->setTipText(i18n("Close") );
416 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(closeWindow()));
417
418 m_button[CloseButton] = btn;
419 }
420 break;
421 case 'F': // AboveButton button
422 if (!m_button[AboveButton]){
423 btn = createButton(AboveButton);
424 if (!btn) break;
425 bool above = keepAbove();
426 btn->setTipText(above?i18n("Do not keep above others"):i18n("Keep above others") );
427 btn->setToggleButton(true);
428 btn->setOn( above );
429 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotKeepAbove()));
430
431 m_button[AboveButton] = btn;
432 }
433 break;
434 case 'B': // BelowButton button
435 if (!m_button[BelowButton]){
436 btn = createButton(BelowButton);
437 if (!btn) break;
438 bool below = keepBelow();
439 btn->setTipText(below?i18n("Do not keep below others"):i18n("Keep below others") );
440 btn->setToggleButton(true);
441 btn->setOn( below );
442 connect(btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotKeepBelow()));
443
444 m_button[BelowButton] = btn;
445 }
446 break;
447 case 'L': // Shade button
448 if ((!m_button[ShadeButton]) && isShadeable()){
449 btn = createButton(ShadeButton);
450 if (!btn) break;
451 bool shaded = isSetShade();
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()));
456
457 m_button[ShadeButton] = btn;
458 }
459 break;
460 case '_': // Spacer item
461 btnContainer.append(0);
462 }
463
464
465 if (btn) {
466 btn->setLeft(isLeft);
467 btn->setSize(TQSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) );
468 btn->show();
469 btnContainer.append(btn);
470 }
471
472 }
473 }
474}
475
476void KCommonDecoration::calcHiddenButtons()
477{
478 if (width() == btnHideLastWidth)
479 return;
480
481 btnHideLastWidth = width();
482
483 //Hide buttons in the following order:
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 ] );
488
489 int current_width = width();
490 int count = 0;
491
492 // Hide buttons
493 while (current_width < btnHideMinWidth && count < buttonsCount)
494 {
495 if (btnArray[count] ) {
496 current_width += btnArray[count]->width();
497 if (btnArray[count]->isVisible() )
498 btnArray[count]->hide();
499 }
500 count++;
501 }
502 // Show the rest of the buttons...
503 for(int i = count; i < buttonsCount; i++)
504 {
505 if (btnArray[i] ) {
506
507 if (! btnArray[i]->isHidden() )
508 break; // all buttons shown...
509
510 btnArray[i]->show();
511 }
512 }
513}
514
515void KCommonDecoration::show()
516{
517 if (decorationBehaviour(DB_ButtonHide) )
518 calcHiddenButtons();
519 widget()->show();
520}
521
522void KCommonDecoration::resize( const TQSize& s )
523{
524 widget()->resize( s );
525}
526
527TQSize KCommonDecoration::minimumSize() const
528{
529 const int minWidth = TQMAX(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
530 +TQMAX(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
531 +layoutMetric(LM_TitleBorderLeft)+layoutMetric(LM_TitleBorderRight);
532 return TQSize(minWidth,
533 layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)
534 +layoutMetric(LM_TitleEdgeBottom)
535 +layoutMetric(LM_BorderBottom) );
536}
537
538void KCommonDecoration::maximizeChange()
539{
540 if( m_button[MaxButton] ) {
541 m_button[MaxButton]->setOn( maximizeMode()==MaximizeFull);
542 m_button[MaxButton]->setTipText( (maximizeMode()!=MaximizeFull) ?
543 i18n("Maximize")
544 : i18n("Restore"));
545 m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
546 }
547 updateWindowShape();
548 widget()->update();
549}
550
551void KCommonDecoration::desktopChange()
552{
553 if ( m_button[OnAllDesktopsButton] ) {
554 m_button[OnAllDesktopsButton]->setOn( isOnAllDesktops() );
555 m_button[OnAllDesktopsButton]->setTipText( isOnAllDesktops() ?
556 i18n("Not on all desktops")
557 : i18n("On all desktops"));
558 m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
559 }
560}
561
562void KCommonDecoration::shadeChange()
563{
564 if ( m_button[ShadeButton] ) {
565 bool shaded = isSetShade();
566 m_button[ShadeButton]->setOn( shaded );
567 m_button[ShadeButton]->setTipText( shaded ?
568 i18n("Unshade")
569 : i18n("Shade"));
570 m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
571 }
572}
573
574void KCommonDecoration::iconChange()
575{
576 if (m_button[MenuButton])
577 {
578 m_button[MenuButton]->update();
579 m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
580 }
581}
582
583void KCommonDecoration::activeChange()
584{
585 updateButtons();
586 widget()->update(); // do something similar to updateCaption here
587}
588
589void KCommonDecoration::captionChange()
590{
591 updateCaption();
592}
593
594void KCommonDecoration::keepAboveChange(bool above)
595{
596 if (m_button[AboveButton])
597 {
598 m_button[AboveButton]->setOn(above);
599 m_button[AboveButton]->setTipText( above?i18n("Do not keep above others"):i18n("Keep above others") );
600 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
601 }
602
603 if (m_button[BelowButton] && m_button[BelowButton]->isOn())
604 {
605 m_button[BelowButton]->setOn(false);
606 m_button[BelowButton]->setTipText( i18n("Keep below others") );
607 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
608 }
609}
610
611void KCommonDecoration::keepBelowChange(bool below)
612{
613 if (m_button[BelowButton])
614 {
615 m_button[BelowButton]->setOn(below);
616 m_button[BelowButton]->setTipText( below?i18n("Do not keep below others"):i18n("Keep below others") );
617 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
618 }
619
620 if (m_button[AboveButton] && m_button[AboveButton]->isOn())
621 {
622 m_button[AboveButton]->setOn(false);
623 m_button[AboveButton]->setTipText( i18n("Keep above others") );
624 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
625 }
626}
627
628void KCommonDecoration::slotMaximize()
629{
630 if (m_button[MaxButton])
631 {
632 maximize(m_button[MaxButton]->lastMousePress() );
633 }
634}
635
636void KCommonDecoration::slotShade()
637{
638 setShade( !isSetShade() );
639}
640
641void KCommonDecoration::slotKeepAbove()
642{
643 setKeepAbove(!keepAbove() );
644}
645
646void KCommonDecoration::slotKeepBelow()
647{
648 setKeepBelow(!keepBelow() );
649}
650
651void KCommonDecoration::menuButtonPressed()
652{
653 static TQTime* t = NULL;
654 static KCommonDecoration* lastClient = NULL;
655 if (t == NULL)
656 t = new TQTime;
657 bool dbl = (lastClient==this && t->elapsed() <= TQApplication::doubleClickInterval());
658 lastClient = this;
659 t->start();
660 if (!dbl || !decorationBehaviour(DB_MenuClose) ) {
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();
665 showWindowMenu(TQRect(menutop, menubottom));
666 if( !f->exists( this )) // 'this' was deleted
667 return;
668 m_button[MenuButton]->setDown(false);
669 }
670 else
671 closing = true;
672}
673
674void KCommonDecoration::menuButtonReleased()
675{
676 if(closing)
677 closeWindow();
678}
679
680void KCommonDecoration::resizeEvent(TQResizeEvent */*e*/)
681{
682 if (decorationBehaviour(DB_ButtonHide) )
683 calcHiddenButtons();
684
685 updateLayout();
686
687 updateWindowShape();
688 // FIXME: don't update() here! this would result in two paintEvent()s
689 // because there is already "something" else triggering the repaint...
690// widget()->update();
691}
692
693void KCommonDecoration::moveWidget(int x, int y, TQWidget *widget) const
694{
695 TQPoint p = widget->pos();
696 int oldX = p.y();
697 int oldY = p.x();
698
699 if (x!=oldX || y!=oldY)
700 widget->move(x,y);
701}
702
703void KCommonDecoration::resizeWidget(int w, int h, TQWidget *widget) const
704{
705 TQSize s = widget->size();
706 int oldW = s.width();
707 int oldH = s.height();
708
709 if (w!=oldW || h!=oldH)
710 widget->resize(w,h);
711}
712
713void KCommonDecoration::mouseDoubleClickEvent(TQMouseEvent *e)
714{
715 if( e->button() != TQt::LeftButton )
716 return;
717
718 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
719 // when shaded, react on double clicks everywhere to make it easier to unshade. otherwise
720 // react only on double clicks in the title bar region...
721 if (isSetShade() || e->pos().y() <= tb )
722 titlebarDblClickOperation();
723}
724
725void KCommonDecoration::wheelEvent(TQWheelEvent *e)
726{
727 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
728 if (isSetShade() || e->pos().y() <= tb )
729 titlebarMouseWheelOperation( e->delta());
730}
731
732KCommonDecoration::Position KCommonDecoration::mousePosition(const TQPoint &point) const
733{
734 //q4os: scale the corner resize-grab zone's base offset with the
735 //session's DPI (same env var/convention as the border-width scaling
736 //in clients/plastik/plastik.cpp) - the "18" here is a literal pixel
737 //constant shared by every KCommonDecoration-derived theme (not just
738 //Plastik) and stays a tiny, hard-to-hit target at high DPI otherwise;
739 //the layoutMetric(LM_BorderBottom) term already scales for themes
740 //(like Plastik) whose own border width is DPI-aware.
741 int q4CornerBase=18;
742 {
743 const char *q4dpistr=getenv("Q4DPI");
744 int q4dpi=q4dpistr ? atoi(q4dpistr) : 0;
745 if(q4dpi>10 && q4dpi<2000)
746 q4CornerBase=(18*q4dpi)/96;
747 }
748 const int corner = q4CornerBase+3*layoutMetric(LM_BorderBottom, false)/2;
749 Position pos = PositionCenter;
750
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);
754 int p_x = point.x();
755 int p_y = point.y();
756 const int borderLeft = layoutMetric(LM_BorderLeft);
757// const int borderRight = layoutMetric(LM_BorderRight);
758 const int borderBottom = layoutMetric(LM_BorderBottom);
759 const int titleHeight = layoutMetric(LM_TitleHeight);
760 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
761 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
762 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
763 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
764
765 const int borderBottomTop = r_y2-borderBottom+1;
766 const int borderLeftRight = r_x+borderLeft-1;
767// const int borderRightLeft = r_x2-borderRight+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;
772
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;
778 else
779 pos = PositionTop;
780 } else if (p_y <= titleEdgeBottomBottom) {
781 if (p_x <= titleEdgeLeftRight)
782 pos = PositionTopLeft;
783 else if (p_x >= titleEdgeRightLeft)
784 pos = PositionTopRight;
785 else
786 pos = PositionCenter; // title bar
787 } else if (p_y < borderBottomTop) {
788 if (p_y < r_y2-corner) {
789 if (p_x <= borderLeftRight)
790 pos = PositionLeft;
791 else
792 pos = PositionRight;
793 } else {
794 if (p_x <= borderLeftRight)
795 pos = PositionBottomLeft;
796 else
797 pos = PositionBottomRight;
798 }
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;
804 else
805 pos = PositionBottom;
806 }
807
808 return pos;
809}
810
811void KCommonDecoration::updateWindowShape()
812{
813 // don't mask the widget...
814 if (!decorationBehaviour(DB_WindowMask) )
815 return;
816
817 int w = widget()->width();
818 int h = widget()->height();
819
820 bool tl=true,tr=true,bl=true,br=true; // is there a transparent rounded corner in top-left? etc
821
822 TQDesktopWidget *desktop=TDEApplication::desktop();
823 // no transparent rounded corners if this window corner lines up with a screen corner
824 for(int screen=0; screen < desktop->numScreens(); ++screen)
825 {
826 TQRect fullscreen(desktop->screenGeometry(screen));
827 TQRect window = geometry();
828
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;
833 }
834
835 TQRegion mask(0, 0, w, h);
836
837 // Remove top-left corner.
838 if(tl)
839 {
840 mask -= cornerShape(WC_TopLeft);
841 }
842 // Remove top-right corner.
843 if(tr)
844 {
845 mask -= cornerShape(WC_TopRight);
846 }
847 // Remove top-left corner.
848 if(bl)
849 {
850 mask -= cornerShape(WC_BottomLeft);
851 }
852 // Remove top-right corner.
853 if(br)
854 {
855 mask -= cornerShape(WC_BottomRight);
856 }
857
858 setMask( mask );
859}
860
861bool KCommonDecoration::eventFilter( TQObject* o, TQEvent* e )
862{
863 if( o != widget())
864 return false;
865 switch( e->type())
866 {
867 case TQEvent::Resize:
868 resizeEvent(static_cast<TQResizeEvent*>(e) );
869 return true;
870 case TQEvent::Paint:
871 paintEvent(static_cast<TQPaintEvent*>( e ));
872 return true;
873 case TQEvent::MouseButtonDblClick:
874 mouseDoubleClickEvent(static_cast<TQMouseEvent*>( e ));
875 return true;
876 case TQEvent::MouseButtonPress:
877 processMousePressEvent(static_cast<TQMouseEvent*>( e ));
878 return true;
879 case TQEvent::Wheel:
880 wheelEvent(static_cast<TQWheelEvent*>( e ));
881 return true;
882 default:
883 return false;
884 }
885}
886
887const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
888 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
889 | NET::UtilityMask | NET::SplashMask;
890
891bool KCommonDecoration::isToolWindow() const
892{
893 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
894 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
895}
896
897TQRect KCommonDecoration::titleRect() const
898{
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);
902 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
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);
907 const int ttlHeight = layoutMetric(LM_TitleHeight);
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) );
912}
913
914
915KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent, const char *name)
916 : TQButton(parent->widget(), name),
917 m_decoration(parent),
918 m_type(type),
919 m_realizeButtons(TQt::LeftButton),
920 m_lastMouse(TQt::NoButton),
921 m_isLeft(true)
922{
923 setCursor(ArrowCursor);
924}
925
926KCommonDecorationButton::~KCommonDecorationButton()
927{
928}
929
930KCommonDecoration *KCommonDecorationButton::decoration() const
931{
932 return m_decoration;
933}
934
935ButtonType KCommonDecorationButton::type() const
936{
937 return m_type;
938}
939
940bool KCommonDecorationButton::isLeft() const
941{
942 return m_isLeft;
943}
944
945void KCommonDecorationButton::setLeft(bool left)
946{
947 m_isLeft = left;
948}
949
950void KCommonDecorationButton::setRealizeButtons(int btns)
951{
952 m_realizeButtons = btns;
953}
954
955void KCommonDecorationButton::setSize(const TQSize &s)
956{
957 if (!m_size.isValid() || s != size() ) {
958 m_size = s;
959
960 setFixedSize(m_size);
961 reset(SizeChange);
962 }
963}
964
965TQSize KCommonDecorationButton::sizeHint() const
966{
967 return m_size;
968}
969
970void KCommonDecorationButton::setTipText(const TQString &tip) {
971 TQToolTip::remove(this );
972 TQToolTip::add(this, tip );
973}
974
975void KCommonDecorationButton::setToggleButton(bool toggle)
976{
977 TQButton::setToggleButton(toggle);
978 reset(ToggleChange);
979}
980
981void KCommonDecorationButton::setOn(bool on)
982{
983 if (on != isOn() ) {
984 TQButton::setOn(on);
985 reset(StateChange);
986 }
987}
988
989void KCommonDecorationButton::mousePressEvent(TQMouseEvent* e)
990{
991 m_lastMouse = e->button();
992 // pass on event after changing button to LeftButton
993 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
994 (e->button()&m_realizeButtons)?TQt::LeftButton:TQt::NoButton, e->state());
995
996 TQButton::mousePressEvent(&me);
997}
998
999void KCommonDecorationButton::mouseReleaseEvent(TQMouseEvent* e)
1000{
1001 m_lastMouse = e->button();
1002 // pass on event after changing button to LeftButton
1003 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
1004 (e->button()&m_realizeButtons)?TQt::LeftButton:TQt::NoButton, e->state());
1005
1006 TQButton::mouseReleaseEvent(&me);
1007}
KCommonDecorationButton
Title bar buttons of KCommonDecoration need to inherit this class.
Definition kcommondecoration.h:293
KCommonDecorationButton::reset
virtual void reset(unsigned long changed)=0
Initialize the button after size change etc.
KCommonDecorationButton::SizeChange
@ SizeChange
The button size changed.
Definition kcommondecoration.h:309
KCommonDecorationButton::ManualReset
@ ManualReset
The button might want to do a full reset for some reason...
Definition kcommondecoration.h:308
KCommonDecorationButton::ToggleChange
@ ToggleChange
The button toggle state has changed.
Definition kcommondecoration.h:310
KCommonDecorationButton::IconChange
@ IconChange
The window icon has been changed.
Definition kcommondecoration.h:312
KCommonDecorationButton::StateChange
@ StateChange
The button has been set pressed or not...
Definition kcommondecoration.h:311
KCommonDecorationButton::setSize
void setSize(const TQSize &s)
Set the button size.
Definition kcommondecoration.cpp:955
KCommonDecorationButton::setTipText
void setTipText(const TQString &tip)
Set/update the button's tool tip.
Definition kcommondecoration.cpp:970
KCommonDecorationButton::type
ButtonType type() const
Definition kcommondecoration.cpp:935
KCommonDecorationButton::decoration
KCommonDecoration * decoration() const
Definition kcommondecoration.cpp:930
KCommonDecorationButton::setRealizeButtons
void setRealizeButtons(int btns)
Set which mouse buttons the button should honor.
Definition kcommondecoration.cpp:950
KCommonDecorationButton::isLeft
bool isLeft() const
Whether the button is left of the titlebar or not.
Definition kcommondecoration.cpp:940
KCommonDecoration
This class eases development of decorations by implementing parts of KDecoration which are error pron...
Definition kcommondecoration.h:60
KCommonDecoration::borders
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.
Definition kcommondecoration.cpp:152
KCommonDecoration::cornerShape
virtual TQRegion cornerShape(WindowCorner corner)
Definition kcommondecoration.cpp:141
KCommonDecoration::maximizeChange
virtual void maximizeChange()
This function is called whenever the maximalization state of the window changes.
Definition kcommondecoration.cpp:538
KCommonDecoration::defaultButtonsRight
virtual TQString defaultButtonsRight() const =0
The default title button order on the left.
KCommonDecoration::decorationBehaviour
virtual bool decorationBehaviour(DecorationBehaviour behaviour) const
This controls whether some specific behaviour should be enabled or not.
Definition kcommondecoration.cpp:65
KCommonDecoration::createButton
virtual KCommonDecorationButton * createButton(ButtonType type)=0
Create a new title bar button.
KCommonDecoration::visibleName
virtual TQString visibleName() const =0
The name of the decoration used in the decoration preview.
KCommonDecoration::updateButtons
void updateButtons() const
Makes sure all buttons are repainted.
Definition kcommondecoration.cpp:244
KCommonDecoration::minimumSize
virtual TQSize minimumSize() const
This function should return the minimum required size for the decoration.
Definition kcommondecoration.cpp:527
KCommonDecoration::activeChange
virtual void activeChange()
This function is called whenever the window either becomes or stops being active.
Definition kcommondecoration.cpp:583
KCommonDecoration::paintEvent
virtual void paintEvent(TQPaintEvent *e)=0
Draw the window decoration.
KCommonDecoration::DecorationBehaviour
DecorationBehaviour
Definition kcommondecoration.h:121
KCommonDecoration::DB_ButtonHide
@ DB_ButtonHide
Hide buttons when there is not enough space in the titlebar.
Definition kcommondecoration.h:124
KCommonDecoration::DB_WindowMask
@ DB_WindowMask
Set a mask on the window.
Definition kcommondecoration.h:123
KCommonDecoration::DB_MenuClose
@ DB_MenuClose
Close window on double clicking the menu.
Definition kcommondecoration.h:122
KCommonDecoration::init
virtual void init()
Handles widget and layout creation, call the base implementation when subclassing this member.
Definition kcommondecoration.cpp:116
KCommonDecoration::defaultButtonsLeft
virtual TQString defaultButtonsLeft() const =0
The default title button order on the left.
KCommonDecoration::shadeChange
virtual void shadeChange()
This function is called whenever the window is shaded or unshaded.
Definition kcommondecoration.cpp:562
KCommonDecoration::titleRect
TQRect titleRect() const
Convenience method.
Definition kcommondecoration.cpp:897
KCommonDecoration::isToolWindow
bool isToolWindow() const
Convenience method.
Definition kcommondecoration.cpp:891
KCommonDecoration::LayoutMetric
LayoutMetric
Used to calculate the decoration layout.
Definition kcommondecoration.h:101
KCommonDecoration::iconChange
virtual void iconChange()
This function is called whenever the window icon changes.
Definition kcommondecoration.cpp:574
KCommonDecoration::updateCaption
virtual void updateCaption()
This is used to update the painting of the title bar after the caption has been changed.
Definition kcommondecoration.cpp:146
KCommonDecoration::updateWindowShape
virtual void updateWindowShape()
This updates the window mask using the information provided by cornerShape().
Definition kcommondecoration.cpp:811
KCommonDecoration::captionChange
virtual void captionChange()
This function is called whenever the caption changes.
Definition kcommondecoration.cpp:589
KCommonDecoration::reset
virtual void reset(unsigned long changed)
Handles SettingButtons, call the base implementation when subclassing this member.
Definition kcommondecoration.cpp:133
KCommonDecoration::resize
virtual void resize(const TQSize &s)
This method is called by twin when the style should resize the decoration window.
Definition kcommondecoration.cpp:522
KCommonDecoration::layoutMetric
virtual int layoutMetric(LayoutMetric lm, bool respectWindowState=true, const KCommonDecorationButton *button=0) const
This controls the layout of the decoration in various ways.
Definition kcommondecoration.cpp:81
KCommonDecoration::updateLayout
void updateLayout() const
TODO: remove?
Definition kcommondecoration.cpp:164
KCommonDecoration::desktopChange
virtual void desktopChange()
This function is called whenever the desktop for the window changes.
Definition kcommondecoration.cpp:551
KCommonDecoration::resetButtons
void resetButtons() const
Manually call reset() on each button.
Definition kcommondecoration.cpp:250
KCommonDecoration::mousePosition
virtual Position mousePosition(const TQPoint &point) const
This function should return mouse cursor position in the decoration.
Definition kcommondecoration.cpp:732
KDecorationDefines::SettingButtons
@ SettingButtons
The button layout was changed.
Definition kdecoration.h:132
KDecorationDefines::Position
Position
These values represent positions inside an area.
Definition kdecoration.h:54
KDecorationDefines::MaximizeFull
@ MaximizeFull
Equal to MaximizeVertical | MaximizeHorizontal.
Definition kdecoration.h:75
KDecoration
This is the base class for a decoration object.
Definition kdecoration.h:315
KDecoration::processMousePressEvent
void processMousePressEvent(TQMouseEvent *e)
This function is the default handler for mouse events.
Definition kdecoration.cpp:174
KDecoration::options
static const KDecorationOptions * options()
Returns the KDecorationOptions object, which is used to access configuration settings for the decorat...
Definition kdecoration.cpp:55
KDecoration::isMinimizable
bool isMinimizable() const
Returns true if the decorated window can be minimized by the user.
Definition kdecoration.cpp:104
KDecoration::closeWindow
void closeWindow()
This function can be called by the decoration to request closing of the decorated window.
Definition kdecoration.cpp:234
KDecoration::setShade
void setShade(bool set)
Shades or unshades the decorated window.
Definition kdecoration.cpp:282
KDecoration::maximizeMode
MaximizeMode maximizeMode() const
Returns the current maximization mode of the decorated window.
Definition kdecoration.cpp:99
KDecoration::keepAbove
bool keepAbove() const
Returns true if the decorated window should be kept above other windows.
Definition kdecoration.cpp:139
KDecoration::isPreview
bool isPreview() const
If this function returns true, the decorated window is used as a preview e.g.
Definition kdecoration.cpp:204
KDecoration::isShadeable
bool isShadeable() const
Returns true if the decorated window can be shaded.
Definition kdecoration.cpp:124
KDecoration::isSetShade
bool isSetShade() const
Returns true if the decorated window was set to be shaded.
Definition kdecoration.cpp:134
KDecoration::showWindowMenu
void showWindowMenu(const TQRect &pos)
This function invokes the window operations menu.
Definition kdecoration.cpp:179
KDecoration::keepBelow
bool keepBelow() const
Returns true if the decorated window should be kept below other windows.
Definition kdecoration.cpp:144
KDecoration::geometry
TQRect geometry() const
Returns the geometry of the decoration.
Definition kdecoration.cpp:209
KDecoration::windowId
WId windowId() const
Returns the handle of the window that is being decorated.
Definition kdecoration.cpp:229
KDecoration::showContextHelp
void showContextHelp()
Start showing context help in the window (i.e.
Definition kdecoration.cpp:254
KDecoration::isMaximizable
bool isMaximizable() const
Returns true if the decorated window can be maximized.
Definition kdecoration.cpp:94
KDecoration::height
int height() const
Convenience function that returns the height of the decoration.
Definition kdecoration.h:885
KDecoration::widget
TQWidget * widget()
Returns the main widget for the decoration.
Definition kdecoration.h:860
KDecoration::setKeepAbove
void setKeepAbove(bool set)
Sets or reset keeping this window above others.
Definition kdecoration.cpp:287
KDecoration::createMainWidget
void createMainWidget(TQt::WFlags flags=0)
Convenience functions that creates and sets a main widget as necessary.
Definition kdecoration.cpp:60
KDecoration::factory
KDecorationFactory * factory() const
Returns the factory that created this decoration.
Definition kdecoration.h:870
KDecoration::setKeepBelow
void setKeepBelow(bool set)
Sets or reset keeping this window below others.
Definition kdecoration.cpp:292
KDecoration::minimize
void minimize()
Minimize the decorated window.
Definition kdecoration.cpp:249
KDecoration::titlebarDblClickOperation
void titlebarDblClickOperation()
This function performs the operation configured as titlebar double click operation.
Definition kdecoration.cpp:272
KDecoration::providesContextHelp
bool providesContextHelp() const
Return true if the decorated window can show context help (i.e.
Definition kdecoration.cpp:109
KDecoration::desktop
int desktop() const
Returns the number of the virtual desktop the decorated window is currently on (including NET::OnAllD...
Definition kdecoration.cpp:114
KDecoration::isCloseable
bool isCloseable() const
Returns true if the decoration window can be closed by the user.
Definition kdecoration.cpp:89
KDecoration::keepBelowChanged
void keepBelowChanged(bool)
This signal is emitted whenever the window's keep-below state changes.
KDecoration::keepAboveChanged
void keepAboveChanged(bool)
This signal is emitted whenever the window's keep-above state changes.
KDecoration::isOnAllDesktops
bool isOnAllDesktops() const
Convenience function that returns true if the window is on all virtual desktops.
Definition kdecoration.h:875
KDecoration::setMask
void setMask(const TQRegion &reg, int mode=0)
If the decoration is non-rectangular, this function needs to be called to set the shape of the decora...
Definition kdecoration.cpp:194
KDecoration::titlebarMouseWheelOperation
void titlebarMouseWheelOperation(int delta)
This function performs the operation configured as titlebar wheel mouse operation.
Definition kdecoration.cpp:277
KDecoration::toggleOnAllDesktops
void toggleOnAllDesktops()
This function toggles the on-all-desktops state of the decorated window.
Definition kdecoration.cpp:264
KDecoration::windowType
NET::WindowType windowType(unsigned long supported_types) const
This function returns the window type of the decorated window.
Definition kdecoration.cpp:159
KDecoration::width
int width() const
Convenience function that returns the width of the decoration.
Definition kdecoration.h:880

twin/lib

Skip menu "twin/lib"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

twin/lib

Skip menu "twin/lib"
  • kate
  • libkonq
  • twin
  •   lib
Generated for twin/lib by doxygen 1.9.8
This website is maintained by Timothy Pearson.