1 #include "nextclient.h"
10 #include <QPaintEvent>
12 #include <QHBoxLayout>
15 #include <QVBoxLayout>
16 #include <QResizeEvent>
17 #include <QMouseEvent>
20 #include <kpixmapeffect.h>
24 static const unsigned char close_bits
[] = {
25 0x03, 0x03, 0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00,
26 0xfc, 0x00, 0xce, 0x01, 0x87, 0x03, 0x03, 0x03};
28 static const unsigned char iconify_bits
[] = {
29 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03,
30 0x03, 0x03, 0x03, 0x03, 0xff, 0x03, 0xff, 0x03};
32 static const unsigned char question_bits
[] = {
33 0x00, 0x00, 0x78, 0x00, 0xcc, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00,
34 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};
36 static const unsigned char sticky_bits
[] = {
37 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01,
38 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};
40 static const unsigned char unsticky_bits
[] = {
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
44 static const unsigned char maximize_bits
[] = {
45 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01,
46 0x02, 0x01, 0x84, 0x00, 0x48, 0x00, 0x30, 0x00 };
48 static const unsigned char shade_bits
[] = {
61 static const unsigned char unshade_bits
[] = {
74 static const unsigned char keep_above_bits
[] = {
87 static const unsigned char from_above_bits
[] = {
100 static const unsigned char keep_below_bits
[] = {
113 static const unsigned char from_below_bits
[] = {
126 static const unsigned char resize_bits
[] = {
140 // If the maximize graphic above (which I did quickly in about a
141 // minute, just so I could have something) doesn't please, maybe one
142 // of the following would be better. IMO it doesn't matter, as long
143 // as it's not offensive---people will get used to whatever you use.
144 // True NeXT fans won't turn on the maximize button anyway.
146 // static const unsigned char maximize_bits[] = {
147 // 0xcf, 0x03, 0x87, 0x03, 0xcf, 0x03, 0xfd, 0x02, 0x48, 0x00, 0x48, 0x00,
148 // 0xfd, 0x02, 0xcf, 0x03, 0x87, 0x03, 0xcf, 0x03 };
150 // static const unsigned char maximize_bits[] = {
151 // 0xcf, 0x03, 0x87, 0x03, 0x87, 0x03, 0x79, 0x02, 0x48, 0x00, 0x48, 0x00,
152 // 0x79, 0x02, 0x87, 0x03, 0x87, 0x03, 0xcf, 0x03 };
154 // static const unsigned char maximize_bits[] = {
155 // 0x87, 0x03, 0x03, 0x03, 0xfd, 0x02, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00,
156 // 0x84, 0x00, 0xfd, 0x02, 0x03, 0x03, 0x87, 0x03 };
158 // static const unsigned char maximize_bits[] = {
159 // 0x30, 0x00, 0x78, 0x00, 0xcc, 0x00, 0x86, 0x01, 0x33, 0x03, 0x79, 0x02,
160 // 0xcd, 0x02, 0x87, 0x03, 0x03, 0x03, 0x01, 0x02 };
162 // static const unsigned char maximize_bits[] = {
163 // 0x30, 0x00, 0x78, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfe, 0x01,
164 // 0xfe, 0x01, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03 };
167 static KPixmap
*aTitlePix
;
168 static KPixmap
*iTitlePix
;
169 static KPixmap
*aFramePix
;
170 static KPixmap
*iFramePix
;
171 static KPixmap
*aHandlePix
;
172 static KPixmap
*iHandlePix
;
173 static KPixmap
*aBtn
;
174 static KPixmap
*aBtnDown
;
175 static KPixmap
*iBtn
;
176 static KPixmap
*iBtnDown
;
177 static QColor
*btnForeground
;
178 static bool pixmaps_created
= false;
180 static int titleHeight
= 16;
182 // Precomputed border sizes for accessibility
183 // The sizes are applied for tiny -> normal -> large -> very large -> huge -> very huge -> oversized
184 static const int borderSizes
[] = { 4, 6, 9, 14, 21, 32, 48 };
186 static int handleSize
= 6; // the resize handle size in pixels
188 static inline const KDecorationOptions
* options()
190 return KDecoration::options();
193 static void create_pixmaps(NextClientFactory
*f
)
197 pixmaps_created
= true;
199 // find preferred border size
200 int i
= options()->preferredBorderSize(f
);
201 if (i
>= 0 && i
<= 6) handleSize
= borderSizes
[i
];
203 titleHeight
= QFontMetrics(options()->font(true)).height() + 4;
204 if (titleHeight
< handleSize
) titleHeight
= handleSize
;
205 titleHeight
&= ~1; // Make title height even
206 if (titleHeight
< 16) titleHeight
= 16;
208 aTitlePix
= new KPixmap();
209 aTitlePix
->resize(32, titleHeight
- 2);
210 KPixmapEffect::gradient(*aTitlePix
,
211 options()->color(KDecoration::ColorTitleBar
, true),
212 options()->color(KDecoration::ColorTitleBlend
, true),
213 KPixmapEffect::VerticalGradient
);
214 iTitlePix
= new KPixmap();
215 iTitlePix
->resize(32, titleHeight
- 2);
216 KPixmapEffect::gradient(*iTitlePix
,
217 options()->color(KDecoration::ColorTitleBar
, false),
218 options()->color(KDecoration::ColorTitleBlend
, false),
219 KPixmapEffect::VerticalGradient
);
220 // Bottom frame gradient
221 aFramePix
= new KPixmap();
222 aFramePix
->resize(32, handleSize
);
223 KPixmapEffect::gradient(*aFramePix
,
224 options()->color(KDecoration::ColorFrame
, true).light(150),
225 options()->color(KDecoration::ColorFrame
, true).dark(120),
226 KPixmapEffect::VerticalGradient
);
227 iFramePix
= new KPixmap();
228 iFramePix
->resize(32, handleSize
);
229 KPixmapEffect::gradient(*iFramePix
,
230 options()->color(KDecoration::ColorFrame
, false).light(150),
231 options()->color(KDecoration::ColorFrame
, false).dark(120),
232 KPixmapEffect::VerticalGradient
);
235 aHandlePix
= new KPixmap();
236 aHandlePix
->resize(32, handleSize
);
237 KPixmapEffect::gradient(*aHandlePix
,
238 options()->color(KDecoration::ColorHandle
, true).light(150),
239 options()->color(KDecoration::ColorHandle
, true).dark(120),
240 KPixmapEffect::VerticalGradient
);
241 iHandlePix
= new KPixmap();
242 iHandlePix
->resize(32, handleSize
);
243 KPixmapEffect::gradient(*iHandlePix
,
244 options()->color(KDecoration::ColorHandle
, false).light(150),
245 options()->color(KDecoration::ColorHandle
, false).dark(120),
246 KPixmapEffect::VerticalGradient
);
248 int btnWidth
= titleHeight
;
250 iBtn
->resize(btnWidth
, btnWidth
);
251 iBtnDown
= new KPixmap
;
252 iBtnDown
->resize(btnWidth
, btnWidth
);
254 aBtn
->resize(btnWidth
, btnWidth
);
255 aBtnDown
= new KPixmap
;
256 aBtnDown
->resize(btnWidth
, btnWidth
);
258 int internalHeight
= btnWidth
- 6;
259 internal
.resize(internalHeight
, internalHeight
);
262 QColor
c(options()->color(KDecoration::ColorButtonBg
, false));
263 KPixmapEffect::gradient(*iBtn
, c
.light(120), c
.dark(120),
264 KPixmapEffect::DiagonalGradient
);
265 KPixmapEffect::gradient(internal
, c
.dark(120), c
.light(120),
266 KPixmapEffect::DiagonalGradient
);
267 bitBlt(iBtn
, 3, 3, &internal
, 0, 0, internalHeight
, internalHeight
, Qt::CopyROP
, true);
269 KPixmapEffect::gradient(*iBtnDown
, c
.dark(120), c
.light(120),
270 KPixmapEffect::DiagonalGradient
);
271 KPixmapEffect::gradient(internal
, c
.light(120), c
.dark(120),
272 KPixmapEffect::DiagonalGradient
);
273 bitBlt(iBtnDown
, 3, 3, &internal
, 0, 0, internalHeight
, internalHeight
, Qt::CopyROP
, true);
276 c
= options()->color(KDecoration::ColorButtonBg
, true);
277 KPixmapEffect::gradient(*aBtn
, c
.light(120), c
.dark(120),
278 KPixmapEffect::DiagonalGradient
);
279 KPixmapEffect::gradient(internal
, c
.dark(120), c
.light(120),
280 KPixmapEffect::DiagonalGradient
);
281 bitBlt(aBtn
, 3, 3, &internal
, 0, 0, internalHeight
, internalHeight
, Qt::CopyROP
, true);
283 KPixmapEffect::gradient(*aBtnDown
, c
.dark(120), c
.light(120),
284 KPixmapEffect::DiagonalGradient
);
285 KPixmapEffect::gradient(internal
, c
.light(120), c
.dark(120),
286 KPixmapEffect::DiagonalGradient
);
287 bitBlt(aBtnDown
, 3, 3, &internal
, 0, 0, internalHeight
, internalHeight
, Qt::CopyROP
, true);
292 p
.drawRect(0, 0, btnWidth
, btnWidth
);
296 p
.drawRect(0, 0, btnWidth
, btnWidth
);
300 p
.drawRect(0, 0, btnWidth
, btnWidth
);
304 p
.drawRect(0, 0, btnWidth
, btnWidth
);
307 if(qGray(options()->color(KDecoration::ColorButtonBg
, true).rgb()) > 128)
308 btnForeground
= new QColor(Qt::black
);
310 btnForeground
= new QColor(Qt::white
);
313 static void delete_pixmaps()
325 delete btnForeground
;
327 pixmaps_created
= false;
330 // =====================================
332 NextButton::NextButton(NextClient
*parent
, const char *name
,
333 const unsigned char *bitmap
, int bw
, int bh
,
334 const QString
& tip
, const int realizeBtns
)
335 : Q3Button(parent
->widget(), name
),
336 deco(NULL
), client(parent
), last_button(Qt::NoButton
)
338 realizeButtons
= realizeBtns
;
340 setBackgroundMode( NoBackground
);
341 resize(titleHeight
, titleHeight
);
342 setFixedSize(titleHeight
, titleHeight
);
345 setBitmap(bitmap
, bw
, bh
);
347 QToolTip::add(this, tip
);
350 void NextButton::reset()
355 void NextButton::setBitmap(const unsigned char *bitmap
, int w
, int h
)
357 deco
= new QBitmap(w
, h
, bitmap
, true);
358 deco
->setMask(*deco
);
362 void NextButton::drawButton(QPainter
*p
)
364 if(client
->isActive())
365 p
->drawPixmap(0, 0, isDown() ? *aBtnDown
: *aBtn
);
367 p
->drawPixmap(0, 0, isDown() ? *iBtnDown
: *iBtn
);
369 // If we have a decoration, draw it; otherwise, we have the menu
370 // button (remember, we set the bitmap to NULL).
373 offset
= (titleHeight
- 10) / 2 + (isDown() ? 1 : 0);
374 p
->setPen(*btnForeground
);
375 p
->drawPixmap(offset
, offset
, *deco
);
377 offset
= (titleHeight
- 16) / 2;
378 KPixmap btnpix
= client
->icon().pixmap(QIcon::Small
,
379 client
->isActive() ? QIcon::Normal
: QIcon::Disabled
);
380 p
->drawPixmap( offset
, offset
, btnpix
);
384 void NextButton::mousePressEvent( QMouseEvent
* e
)
386 last_button
= e
->button();
387 QMouseEvent
me( e
->type(), e
->pos(), e
->globalPos(),
388 (e
->button()&realizeButtons
)?Qt::LeftButton
:Qt::NoButton
, e
->state() );
389 Q3Button::mousePressEvent( &me
);
392 void NextButton::mouseReleaseEvent( QMouseEvent
* e
)
394 last_button
= e
->button();
395 QMouseEvent
me( e
->type(), e
->pos(), e
->globalPos(),
396 (e
->button()&realizeButtons
)?Qt::LeftButton
:Qt::NoButton
, e
->state() );
397 Q3Button::mouseReleaseEvent( &me
);
400 // =====================================
402 NextClient::NextClient(KDecorationBridge
*b
, KDecorationFactory
*f
)
407 void NextClient::init()
409 createMainWidget(WResizeNoErase
| WStaticContents
);
410 widget()->installEventFilter(this);
412 widget()->setBackgroundMode( NoBackground
);
414 QVBoxLayout
*mainLayout
= new QVBoxLayout(widget());
415 QBoxLayout
*titleLayout
= new QBoxLayout(0, QBoxLayout::LeftToRight
, 0, 0, 0);
416 QHBoxLayout
*windowLayout
= new QHBoxLayout();
417 mainLayout
->addLayout(titleLayout
);
418 mainLayout
->addLayout(windowLayout
, 1);
419 mainLayout
->addSpacing(mustDrawHandle() ? handleSize
: 1);
421 windowLayout
->addSpacing(1);
423 windowLayout
->addWidget(new QLabel(i18n(
424 "<center><b>KStep preview</b></center>"), widget()));
426 windowLayout
->addItem(new QSpacerItem( 0, 0 ));
428 windowLayout
->addSpacing(1);
430 initializeButtonsAndTitlebar(titleLayout
);
435 + button is an array of length MAX_NUM_BUTTONS
438 + Title bar and buttons have been initialized and laid out
439 + for all i in 0..(MAX_NUM_BUTTONS-1), button[i] points to
440 either (1) a valid NextButton instance, if the corresponding
441 button is selected in the current button scheme, or (2) null
444 void NextClient::initializeButtonsAndTitlebar(QBoxLayout
* titleLayout
)
446 // Null the buttons to begin with (they are not guaranteed to be null).
447 for (int i
=0; i
<MAX_NUM_BUTTONS
; i
++) {
451 // The default button positions for other styles do not match the
452 // behavior of older versions of KStep, so we have to set these
453 // manually when customButtonPositions isn't enabled.
455 if (options()->customButtonPositions()) {
456 left
= options()->titleButtonsLeft();
457 right
= options()->titleButtonsRight();
460 right
= QString("SX");
463 // Do actual creation and addition to titleLayout
464 addButtons(titleLayout
, left
);
466 titlebar
= new QSpacerItem(10, titleHeight
, QSizePolicy::Expanding
,
467 QSizePolicy::Minimum
);
468 titleLayout
->addItem(titlebar
);
469 addButtons(titleLayout
, right
);
471 // Finally, activate all live buttons
472 for ( int i
= 0; i
< MAX_NUM_BUTTONS
; i
++) {
474 button
[i
]->setMouseTracking( TRUE
);
479 /** Adds the buttons for one side of the title bar, based on the spec
480 * string; see the KWinInternal::KDecoration class, methods
481 * titleButtonsLeft and titleBUttonsRight. */
482 void NextClient::addButtons(QBoxLayout
* titleLayout
, const QString
& spec
)
484 for (unsigned int i
=0; i
<spec
.length(); i
++) {
485 switch (spec
[i
].latin1()) {
487 if (isMaximizable()) {
488 button
[MAXIMIZE_IDX
] =
489 new NextButton(this, "maximize", maximize_bits
, 10, 10,
490 i18n("Maximize"), LeftButton
|MidButton
|RightButton
);
491 titleLayout
->addWidget( button
[MAXIMIZE_IDX
] );
492 connect( button
[MAXIMIZE_IDX
], SIGNAL(clicked()),
493 this, SLOT(maximizeButtonClicked()) );
498 if (providesContextHelp()) {
499 button
[HELP_IDX
] = new NextButton(this,
500 "help", question_bits
, 10, 10, i18n("Help"));
501 titleLayout
->addWidget( button
[HELP_IDX
] );
502 connect( button
[HELP_IDX
], SIGNAL(clicked()),
503 this, SLOT(showContextHelp()) );
508 if (isMinimizable()) {
509 button
[ICONIFY_IDX
] =
510 new NextButton(this, "iconify", iconify_bits
, 10, 10,
512 titleLayout
->addWidget( button
[ICONIFY_IDX
] );
513 connect( button
[ICONIFY_IDX
], SIGNAL(clicked()),
514 this, SLOT(minimize()) );
520 new NextButton(this, "menu", NULL
, 10, 10, i18n("Menu"), LeftButton
|RightButton
);
521 titleLayout
->addWidget( button
[MENU_IDX
] );
522 // NOTE DIFFERENCE: capture pressed(), not clicked()
523 connect( button
[MENU_IDX
], SIGNAL(pressed()),
524 this, SLOT(menuButtonPressed()) );
529 new NextButton(this, "shade", NULL
, 0, 0, i18n("Shade"));
530 titleLayout
->addWidget( button
[SHADE_IDX
] );
531 connect( button
[SHADE_IDX
], SIGNAL(clicked()),
532 this, SLOT(shadeClicked()) );
533 // NOTE DIFFERENCE: set the pixmap separately (2 states)
539 new NextButton(this, "sticky", NULL
, 0, 0, i18n("On all desktops"));
540 titleLayout
->addWidget( button
[STICKY_IDX
] );
541 connect( button
[STICKY_IDX
], SIGNAL(clicked()),
542 this, SLOT(toggleOnAllDesktops()) );
543 // NOTE DIFFERENCE: set the pixmap separately (2 states)
548 button
[ABOVE_IDX
] = new NextButton(this, "above", NULL
, 0, 0, "");
549 titleLayout
->addWidget( button
[ABOVE_IDX
] );
550 connect( button
[ABOVE_IDX
], SIGNAL(clicked()),
551 this, SLOT(aboveClicked()) );
552 connect(this, SIGNAL(keepAboveChanged(bool)),
553 SLOT(keepAboveChange(bool)));
554 keepAboveChange(keepAbove());
558 button
[BELOW_IDX
] = new NextButton(this, "below", NULL
, 0, 0, "");
559 titleLayout
->addWidget( button
[BELOW_IDX
] );
560 connect( button
[BELOW_IDX
], SIGNAL(clicked()),
561 this, SLOT(belowClicked()) );
562 connect(this, SIGNAL(keepBelowChanged(bool)),
563 SLOT(keepBelowChange(bool)));
564 keepBelowChange(keepBelow());
570 new NextButton(this, "close", close_bits
, 10, 10,
572 titleLayout
->addWidget(button
[CLOSE_IDX
]);
573 connect(button
[CLOSE_IDX
], SIGNAL(clicked()),
574 this, SLOT(closeWindow()));
579 if (mustDrawHandle()) {
581 new NextButton(this, "resize", resize_bits
, 10, 10,
583 titleLayout
->addWidget(button
[RESIZE_IDX
]);
584 // NOTE DIFFERENCE: capture pressed(), not clicked()
585 connect(button
[RESIZE_IDX
], SIGNAL(pressed()),
586 this, SLOT(resizePressed()));
590 // TODO: Add spacer handling
594 kdDebug() << " Can't happen: unknown button code "
601 bool NextClient::mustDrawHandle() const
603 bool drawSmallBorders
= !options()->moveResizeMaximizedWindows();
604 if (drawSmallBorders
&& (maximizeMode() & MaximizeVertical
)) {
607 return isResizable();
611 void NextClient::iconChange()
613 if (button
[MENU_IDX
] && button
[MENU_IDX
]->isVisible())
614 button
[MENU_IDX
]->repaint(false);
617 void NextClient::menuButtonPressed()
619 // Probably don't need this null check, but we might as well.
620 if (button
[MENU_IDX
]) {
621 QRect menuRect
= button
[MENU_IDX
]->rect();
622 QPoint menuTop
= button
[MENU_IDX
]->mapToGlobal(menuRect
.topLeft());
623 QPoint menuBottom
= button
[MENU_IDX
]->mapToGlobal(menuRect
.bottomRight());
624 menuTop
+= QPoint(1, 1);
625 menuBottom
+= QPoint(1, 1);
626 KDecorationFactory
* f
= factory();
627 showWindowMenu(QRect(menuTop
, menuBottom
));
628 if( !f
->exists( this )) // 'this' was deleted
630 button
[MENU_IDX
]->setDown(false);
634 // Copied, with minor edits, from KDEDefaultClient::slotMaximize()
635 void NextClient::maximizeButtonClicked()
637 if (button
[MAXIMIZE_IDX
]) {
638 maximize(button
[MAXIMIZE_IDX
]->lastButton());
642 void NextClient::shadeClicked()
644 setShade(!isSetShade());
647 void NextClient::aboveClicked()
649 setKeepAbove(!keepAbove());
652 void NextClient::belowClicked()
654 setKeepBelow(!keepBelow());
655 keepAboveChange(keepAbove());
656 keepBelowChange(keepBelow());
659 void NextClient::resizePressed()
661 performWindowOperation(ResizeOp
);
664 void NextClient::resizeEvent(QResizeEvent
*)
666 if (widget()->isVisible()) {
667 // TODO ? update border area only?
670 widget()->update(titlebar
->geometry());
671 QPainter
p(widget());
672 QRect t
= titlebar
->geometry();
674 QRegion r
= widget()->rect();
676 p
.setClipRegion( r
);
677 p
.eraseRect(widget()->rect());
682 void NextClient::captionChange()
684 widget()->repaint(titlebar
->geometry(), false);
688 void NextClient::paintEvent( QPaintEvent
* )
690 QPainter
p(widget());
693 QRect fr
= widget()->rect();
698 QRect t
= titlebar
->geometry();
700 p
.drawTiledPixmap(t
.x()+1, t
.y()+1, t
.width()-2, t
.height()-2,
701 isActive() ? *aTitlePix
: *iTitlePix
);
702 qDrawShadePanel(&p
, t
.x(), t
.y(), t
.width(), t
.height()-1,
703 options()->colorGroup(KDecoration::ColorTitleBar
, isActive()));
704 p
.drawLine(t
.x(), t
.bottom(), t
.right(), t
.bottom());
707 // Why setting up a clipping region if it is not used? (setClipping(false))
710 p
.setClipRegion( r
);
711 p
.setClipping(false);
715 t
.setHeight(t
.height()-2);
716 t
.setLeft( t
.left() + 4 );
717 t
.setRight( t
.right() - 2 );
719 p
.setPen(options()->color(KDecoration::ColorFont
, isActive()));
720 p
.setFont(options()->font(isActive()));
721 p
.drawText( t
, AlignCenter
| AlignVCenter
, caption() );
723 // Draw resize handle
724 if (mustDrawHandle()) {
725 int corner
= 16 + 3*handleSize
/2;
727 fr
.x() + 1, fr
.bottom() - handleSize
, corner
-1, handleSize
,
728 options()->colorGroup(KDecoration::ColorHandle
, isActive()),
730 p
.drawTiledPixmap(fr
.x() + 2, fr
.bottom() - handleSize
+ 1,
731 corner
- 3, handleSize
- 2, isActive() ? *aHandlePix
: *iHandlePix
);
734 fr
.x() + corner
, fr
.bottom() - handleSize
,
735 fr
.width() - 2*corner
, handleSize
,
736 options()->colorGroup(KDecoration::ColorFrame
, isActive()),
738 p
.drawTiledPixmap(fr
.x() + corner
+ 1, fr
.bottom() - handleSize
+ 1,
739 fr
.width() - 2*corner
- 2, handleSize
- 2,
740 isActive() ? *aFramePix
: *iFramePix
);
743 fr
.right() - corner
+ 1, fr
.bottom() - handleSize
, corner
- 1, handleSize
,
744 options()->colorGroup(KDecoration::ColorHandle
, isActive()),
746 p
.drawTiledPixmap(fr
.right() - corner
+ 2, fr
.bottom() - handleSize
+ 1,
747 corner
- 3, handleSize
- 2, isActive() ? *aHandlePix
: *iHandlePix
);
751 void NextClient::mouseDoubleClickEvent( QMouseEvent
* e
)
753 if (e
->button() == LeftButton
&& titlebar
->geometry().contains( e
->pos() ) )
754 titlebarDblClickOperation();
757 void NextClient::showEvent(QShowEvent
*)
762 void NextClient::desktopChange()
764 bool on
= isOnAllDesktops();
765 if (NextButton
* b
= button
[STICKY_IDX
]) {
766 b
->setBitmap( on
? unsticky_bits
: sticky_bits
, 10, 10);
768 QToolTip::add(b
, on
? i18n("Not on all desktops") : i18n("On all desktops"));
772 void NextClient::maximizeChange()
774 if (button
[MAXIMIZE_IDX
]) {
775 bool m
= maximizeMode() == MaximizeFull
;
776 //button[MAXIMIZE_IDX]->setBitmap(m ? minmax_bits : maximize_bits);
777 QToolTip::remove(button
[MAXIMIZE_IDX
]);
778 QToolTip::add(button
[MAXIMIZE_IDX
],
779 m
? i18n("Restore") : i18n("Maximize"));
781 //spacer->changeSize(10, mustDrawHandle() ? handleSize : 1,
782 // QSizePolicy::Expanding, QSizePolicy::Minimum);
783 //mainLayout->activate();
786 void NextClient::activeChange()
788 widget()->repaint(false);
792 void NextClient::slotReset()
794 for (int i
=0; i
<MAX_NUM_BUTTONS
; i
++) {
801 KDecoration::Position
802 NextClient::mousePosition( const QPoint
& p
) const
804 Position m
= PositionCenter
;
806 if (p
.y() < (height() - handleSize
))
807 m
= KDecoration::mousePosition(p
);
810 int corner
= 16 + 3*handleSize
/2;
811 if (p
.x() >= (width() - corner
))
812 m
= PositionBottomRight
;
813 else if (p
.x() <= corner
)
814 m
= PositionBottomLeft
;
822 void NextClient::borders(int &left
, int &right
, int &top
, int &bottom
) const
825 top
= titleHeight
; // FRAME is this ok?
826 bottom
= mustDrawHandle() ? handleSize
: 1;
829 void NextClient::shadeChange()
831 if (NextButton
*b
= button
[SHADE_IDX
]) {
832 b
->setBitmap(isSetShade() ? unshade_bits
: shade_bits
, 10, 10);
834 QToolTip::add(b
, isSetShade() ? i18n("Unshade") : i18n("Shade"));
838 void NextClient::keepAboveChange(bool above
)
840 if (NextButton
*b
= button
[ABOVE_IDX
]) {
841 b
->setBitmap(above
? from_above_bits
: keep_above_bits
, 10, 10);
843 QToolTip::add(b
, above
?
844 i18n("Do not keep above others") : i18n("Keep above others"));
849 void NextClient::keepBelowChange(bool below
)
851 if (NextButton
*b
= button
[BELOW_IDX
]) {
852 b
->setBitmap(below
? from_below_bits
: keep_below_bits
, 10, 10);
854 QToolTip::add(b
, below
?
855 i18n("Do not keep below others") : i18n("Keep below others"));
860 QSize
NextClient::minimumSize() const
862 return QSize(titleHeight
* 6 + 2, titleHeight
+ handleSize
+ 2);
865 void NextClient::resize(const QSize
& s
)
870 void NextClient::reset(unsigned long)
872 for (int i
= 0; i
< MAX_NUM_BUTTONS
; ++i
) {
879 bool NextClient::eventFilter(QObject
*o
, QEvent
*e
)
885 resizeEvent(static_cast< QResizeEvent
* >( e
));
888 paintEvent(static_cast< QPaintEvent
* >( e
));
890 case QEvent::MouseButtonDblClick
:
891 mouseDoubleClickEvent(static_cast< QMouseEvent
* >( e
));
893 case QEvent::MouseButtonPress
:
894 processMousePressEvent(static_cast< QMouseEvent
* >( e
));
897 showEvent(static_cast< QShowEvent
* >( e
));
905 bool NextClient::drawbound(const QRect
& geom
, bool /* clear */)
907 QPainter
p(workspaceWidget());
908 p
.setPen(QPen(Qt::white
, 3));
909 p
.setRasterOp(Qt::XorROP
);
911 int leftMargin
= geom
.left() + 2;
912 p
.fillRect(leftMargin
, geom
.top() + titleHeight
- 1,
913 geom
.width() - 4, 3, Qt::white
);
914 if (mustDrawHandle()) {
915 p
.fillRect(leftMargin
, geom
.bottom() - handleSize
- 1,
916 geom
.width() - 4, 3, Qt::white
);
921 // =====================================
923 NextClientFactory::NextClientFactory()
925 create_pixmaps(this);
928 NextClientFactory::~NextClientFactory()
933 KDecoration
*NextClientFactory::createDecoration(KDecorationBridge
*b
)
935 return new NextClient(b
, this);
938 bool NextClientFactory::reset(unsigned long /*changed*/)
940 // TODO Do not recreate decorations if it is not needed. Look at
941 // ModernSystem for how to do that
943 create_pixmaps(this);
944 // For now just return true.
948 bool NextClientFactory::supports( Ability ability
)
952 case AbilityAnnounceButtons
:
953 case AbilityButtonMenu
:
954 case AbilityButtonOnAllDesktops
:
955 case AbilityButtonHelp
:
956 case AbilityButtonMinimize
:
957 case AbilityButtonMaximize
:
958 case AbilityButtonClose
:
959 case AbilityButtonAboveOthers
:
960 case AbilityButtonBelowOthers
:
961 case AbilityButtonShade
:
962 case AbilityButtonResize
:
969 QList
< NextClientFactory::BorderSize
>
970 NextClientFactory::borderSizes() const
972 // the list must be sorted
973 return QList
< BorderSize
>() << BorderTiny
<< BorderNormal
<<
974 BorderLarge
<< BorderVeryLarge
<< BorderHuge
<<
975 BorderVeryHuge
<< BorderOversized
;
980 extern "C" KDE_EXPORT KDecorationFactory
* create_factory()
982 return new KStep::NextClientFactory();
985 #include "nextclient.moc"