00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "b2client.h"
00014
#include <qapplication.h>
00015
#include <qlayout.h>
00016
#include <qdrawutil.h>
00017
#include <kpixmapeffect.h>
00018
#include <kimageeffect.h>
00019
#include <kicontheme.h>
00020
#include <kiconeffect.h>
00021
#include <kdrawutil.h>
00022
#include <klocale.h>
00023
#include <kconfig.h>
00024
#include <qbitmap.h>
00025
#include <qlabel.h>
00026
#include <qtooltip.h>
00027
00028
#include <X11/Xlib.h>
00029
00030
namespace B2 {
00031
00032
#include "bitmaps.h"
00033
00034
enum {
00035 Norm = 0,
00036 Hover, Down, INorm, IHover, IDown,
00037 NumStates
00038 };
00039
00040
enum {
00041 P_CLOSE = 0,
00042 P_MAX, P_NORMALIZE, P_ICONIFY, P_PINUP, P_MENU, P_HELP, P_SHADE, P_RESIZE,
00043 P_NUM_BUTTON_TYPES
00044 };
00045
00046
#define NUM_PIXMAPS (P_NUM_BUTTON_TYPES * NumStates)
00047
00048
static KPixmap *pixmap[NUM_PIXMAPS];
00049
00050
00051
#define PIXMAP_A(i) (pixmap[(i) * NumStates + Norm])
00052
00053
#define PIXMAP_AH(i) (pixmap[(i) * NumStates + Hover])
00054
00055
#define PIXMAP_AD(i) (pixmap[(i) * NumStates + Down])
00056
00057
#define PIXMAP_I(i) (pixmap[(i) * NumStates + INorm])
00058
00059
#define PIXMAP_IH(i) (pixmap[(i) * NumStates + IHover])
00060
00061
#define PIXMAP_ID(i) (pixmap[(i) * NumStates + IDown])
00062
00063
static KPixmap* titleGradient[2] = {0, 0};
00064
00065
static int thickness = 4;
00066
static int buttonSize = 16;
00067
00068
enum DblClickOperation {
00069 NoOp = 0,
00070 MinimizeOp,
00071 ShadeOp,
00072 CloseOp
00073 };
00074
00075
static DblClickOperation menu_dbl_click_op = NoOp;
00076
00077
static bool pixmaps_created =
false;
00078
static bool colored_frame =
false;
00079
static bool do_draw_handle =
true;
00080
00081
00082
00083
extern "C" KDecorationFactory* create_factory()
00084 {
00085
return new B2::B2ClientFactory();
00086 }
00087
00088
00089
00090
static inline const KDecorationOptions *options()
00091 {
00092
return KDecoration::options();
00093 }
00094
00095
static void redraw_pixmaps();
00096
00097
static void read_config(B2ClientFactory *f)
00098 {
00099
00100
00101 buttonSize = (QFontMetrics(options()->font(
true)).height() + 1) & 0x3e;
00102
if (buttonSize < 16) buttonSize = 16;
00103
00104 KConfig conf(
"kwinb2rc");
00105 conf.setGroup(
"General");
00106 colored_frame = conf.readBoolEntry(
"UseTitleBarBorderColors",
false);
00107 do_draw_handle = conf.readBoolEntry(
"DrawGrabHandle",
true);
00108 QString opString = conf.readEntry(
"MenuButtonDoubleClickOperation",
"NoOp");
00109
if (opString ==
"Close") {
00110 menu_dbl_click_op = B2::CloseOp;
00111 }
else if (opString ==
"Minimize") {
00112 menu_dbl_click_op = B2::MinimizeOp;
00113 }
else if (opString ==
"Shade") {
00114 menu_dbl_click_op = B2::ShadeOp;
00115 }
else {
00116 menu_dbl_click_op = B2::NoOp;
00117 }
00118
00119
switch (options()->preferredBorderSize(f)) {
00120
case KDecoration::BorderTiny:
00121 thickness = 2;
00122
break;
00123
case KDecoration::BorderLarge:
00124 thickness = 5;
00125
break;
00126
case KDecoration::BorderVeryLarge:
00127 thickness = 8;
00128
break;
00129
case KDecoration::BorderHuge:
00130 thickness = 12;
00131
break;
00132
case KDecoration::BorderVeryHuge:
00133
case KDecoration::BorderOversized:
00134
case KDecoration::BorderNormal:
00135
default:
00136 thickness = 4;
00137 }
00138 }
00139
00140
static void drawB2Rect(KPixmap *pix,
const QColor &primary,
bool down)
00141 {
00142 QPainter p(pix);
00143 QColor hColor = primary.light(150);
00144 QColor lColor = primary.dark(150);
00145
00146
if (QPixmap::defaultDepth() > 8) {
00147
if (down)
00148 KPixmapEffect::gradient(*pix, lColor, hColor,
00149 KPixmapEffect::DiagonalGradient);
00150
else
00151 KPixmapEffect::gradient(*pix, hColor, lColor,
00152 KPixmapEffect::DiagonalGradient);
00153 }
00154
else
00155 pix->fill(primary);
00156
int x2 = pix->width() - 1;
00157
int y2 = pix->height() - 1;
00158 p.setPen(down ? hColor : lColor);
00159 p.drawLine(0, 0, x2, 0);
00160 p.drawLine(0, 0, 0, y2);
00161 p.drawLine(1, x2 - 1, x2 - 1, y2 - 1);
00162 p.drawLine(x2 - 1, 1, x2 - 1, y2 - 1);
00163 p.setPen(down ? lColor : hColor);
00164 p.drawRect(1, 1, x2, y2);
00165
00166 }
00167
00168 QPixmap* kwin_get_menu_pix_hack()
00169 {
00170
00171
return PIXMAP_A(P_MENU);
00172 }
00173
00174
static void create_pixmaps()
00175 {
00176
if (pixmaps_created)
00177
return;
00178 pixmaps_created =
true;
00179
00180
int i;
00181
int bsize = buttonSize - 2;
00182
if (bsize < 16) bsize = 16;
00183
00184
for (i = 0; i < NUM_PIXMAPS; i++) {
00185 pixmap[i] =
new KPixmap;
00186
switch (i / NumStates) {
00187
case P_MAX:
00188
case P_RESIZE:
00189
break;
00190
case P_ICONIFY:
00191 pixmap[i]->resize(10, 10);
break;
00192
case P_SHADE:
00193
case P_CLOSE:
00194 pixmap[i]->resize(bsize, bsize);
break;
00195
default:
00196 pixmap[i]->resize(16, 16);
break;
00197 }
00198 }
00199
00200
00201
00202 QBitmap pinupMask(16, 16, pinup_mask_bits,
true);
00203 PIXMAP_A(P_PINUP)->setMask(pinupMask);
00204 PIXMAP_I(P_PINUP)->setMask(pinupMask);
00205 QBitmap pindownMask(16, 16, pindown_mask_bits,
true);
00206 PIXMAP_AD(P_PINUP)->setMask(pindownMask);
00207 PIXMAP_ID(P_PINUP)->setMask(pindownMask);
00208
00209 QBitmap menuMask(16, 16, menu_mask_bits,
true);
00210
for (i = 0; i < NumStates; i++)
00211 pixmap[P_MENU * NumStates + i]->setMask(menuMask);
00212
00213 QBitmap helpMask(16, 16, help_mask_bits,
true);
00214
for (i = 0; i < NumStates; i++)
00215 pixmap[P_HELP * NumStates + i]->setMask(helpMask);
00216
00217 QBitmap normalizeMask(16, 16,
true);
00218
00219 QPainter mask;
00220 mask.begin(&normalizeMask);
00221
00222 QBrush one(Qt::color1);
00223 mask.fillRect(normalizeMask.width() - 12, normalizeMask.height() - 12,
00224 12, 12, one);
00225 mask.fillRect(0, 0, 10, 10, one);
00226 mask.end();
00227
00228
for (i = 0; i < NumStates; i++)
00229 pixmap[P_NORMALIZE * NumStates + i]->setMask(normalizeMask);
00230
00231 QBitmap shadeMask(bsize, bsize,
true);
00232 mask.begin(&shadeMask);
00233 mask.fillRect(0, 0, bsize, 6, one);
00234 mask.end();
00235
for (i = 0; i < NumStates; i++)
00236 pixmap[P_SHADE * NumStates + i]->setMask(shadeMask);
00237
00238 titleGradient[0] = 0;
00239 titleGradient[1] = 0;
00240
00241 redraw_pixmaps();
00242 }
00243
00244
static void delete_pixmaps()
00245 {
00246
for (
int i = 0; i < NUM_PIXMAPS; i++) {
00247
delete pixmap[i];
00248 pixmap[i] = 0;
00249 }
00250
for (
int i = 0; i < 2; i++) {
00251
delete titleGradient[i];
00252 titleGradient[i] = 0;
00253 }
00254 pixmaps_created =
false;
00255 }
00256
00257
00258
00259 B2ClientFactory::B2ClientFactory()
00260 {
00261 read_config(
this);
00262 create_pixmaps();
00263 }
00264
00265 B2ClientFactory::~B2ClientFactory()
00266 {
00267 delete_pixmaps();
00268 }
00269
00270
KDecoration *B2ClientFactory::createDecoration(KDecorationBridge *b)
00271 {
00272
return new B2::B2Client(b,
this);
00273 }
00274
00275
bool B2ClientFactory::reset(
unsigned long changed)
00276 {
00277
bool needsReset =
SettingColors ?
true :
false;
00278
00279
00280 read_config(
this);
00281
if (changed &
SettingFont) {
00282 delete_pixmaps();
00283 create_pixmaps();
00284 needsReset =
true;
00285 }
00286 redraw_pixmaps();
00287
00288
return needsReset;
00289 }
00290
00291 QValueList< B2ClientFactory::BorderSize > B2ClientFactory::borderSizes()
const
00292
{
00293
00294
return QValueList< BorderSize >() <<
BorderTiny <<
BorderNormal <<
00295
BorderLarge <<
BorderVeryLarge <<
BorderHuge;
00296 }
00297
00298
00299
00300
void B2Client::maxButtonClicked()
00301 {
00302 maximize(button[BtnMax]->last_button);
00303 }
00304
00305
void B2Client::shadeButtonClicked()
00306 {
00307 setShade(!isShade());
00308 }
00309
00310
void B2Client::resizeButtonPressed()
00311 {
00312 performWindowOperation(ResizeOp);
00313 }
00314
00315 B2Client::B2Client(KDecorationBridge *b, KDecorationFactory *f)
00316 :
KDecoration(b, f), bar_x_ofs(0), in_unobs(0)
00317 {
00318 }
00319
00320
void B2Client::init()
00321 {
00322 draw_handle = do_draw_handle;
00323
const QString tips[] = {
00324 i18n(
"Menu"),
00325 isOnAllDesktops() ?
00326 i18n(
"Not on all desktops") : i18n(
"On all desktops"),
00327 i18n(
"Minimize"), i18n(
"Maximize"),
00328 i18n(
"Close"), i18n(
"Help"),
00329 isShade() ? i18n(
"Unshade") : i18n(
"Shade"),
00330 i18n(
"Resize")
00331 };
00332
00333 createMainWidget(WResizeNoErase | WRepaintNoErase);
00334 widget()->installEventFilter(
this);
00335
00336 widget()->setBackgroundMode(NoBackground);
00337
00338
00339
for (
int i = 0; i < BtnCount; i++)
00340 button[i] = NULL;
00341
00342 g =
new QGridLayout(widget(), 0, 0);
00343
if (isPreview()) {
00344 g->addMultiCellWidget(
00345
new QLabel(i18n(
"<b><center>B II preview</center></b>"),
00346 widget()),
00347 1, 1, 1, 2);
00348 }
else {
00349 g->addMultiCell(
new QSpacerItem(0, 0), 1, 1, 1, 2);
00350 }
00351
00352
00353 leftSpacer =
new QSpacerItem(thickness, 16,
00354 QSizePolicy::Minimum, QSizePolicy::Expanding);
00355 rightSpacer =
new QSpacerItem(thickness, 16,
00356 QSizePolicy::Minimum, QSizePolicy::Expanding);
00357
00358 g->addItem(leftSpacer, 1, 0);
00359 g->addColSpacing(1, 16);
00360 g->setColStretch(2, 1);
00361 g->setRowStretch(1, 1);
00362 g->addItem(rightSpacer, 1, 3);
00363
00364
00365 spacer =
new QSpacerItem(10, thickness + (mustDrawHandle() ? 4 : 0),
00366 QSizePolicy::Expanding, QSizePolicy::Minimum);
00367 g->addItem(spacer, 3, 1);
00368
00369
00370 g->addRowSpacing(0, buttonSize + 4);
00371
00372 titlebar =
new B2Titlebar(
this);
00373 titlebar->setMinimumWidth(buttonSize + 4);
00374 titlebar->setFixedHeight(buttonSize + 4);
00375
00376 QBoxLayout *titleLayout =
new QBoxLayout(titlebar,
00377 QBoxLayout::LeftToRight, 0, 1, 0);
00378 titleLayout->addSpacing(3);
00379
00380
if (options()->customButtonPositions()) {
00381 addButtons(options()->titleButtonsLeft(), tips, titlebar, titleLayout);
00382 titleLayout->addItem(titlebar->captionSpacer);
00383 addButtons(options()->titleButtonsRight(), tips, titlebar, titleLayout);
00384 }
else {
00385 addButtons(
"MSH", tips, titlebar, titleLayout);
00386 titleLayout->addItem(titlebar->captionSpacer);
00387 addButtons(
"IAX", tips, titlebar, titleLayout);
00388 }
00389
00390 titleLayout->addSpacing(3);
00391
00392 QColor c = options()->colorGroup(KDecoration::ColorTitleBar, isActive()).
00393 color(QColorGroup::Button);
00394
00395
for (
int i = 0; i < BtnCount; i++) {
00396
if (button[i])
00397 button[i]->setBg(c);
00398 }
00399
00400 titlebar->updateGeometry();
00401 positionButtons();
00402 titlebar->recalcBuffer();
00403 titlebar->installEventFilter(
this);
00404 }
00405
00406
void B2Client::addButtons(
const QString& s,
const QString tips[],
00407 B2Titlebar* tb, QBoxLayout* titleLayout)
00408 {
00409
if (s.length() <= 0)
00410
return;
00411
00412
for (
unsigned int i = 0; i < s.length(); i++) {
00413
switch (s[i].latin1()) {
00414
case 'M':
00415
if (!button[BtnMenu]) {
00416 button[BtnMenu] =
new B2Button(
this, tb, tips[BtnMenu],
00417 LeftButton | RightButton);
00418 button[BtnMenu]->setPixmaps(P_MENU);
00419 button[BtnMenu]->setUseMiniIcon();
00420 connect(button[BtnMenu], SIGNAL(pressed()),
00421
this, SLOT(menuButtonPressed()));
00422 titleLayout->addWidget(button[BtnMenu]);
00423 }
00424
break;
00425
case 'S':
00426
if (!button[BtnSticky]) {
00427 button[BtnSticky] =
new B2Button(
this, tb, tips[BtnSticky]);
00428 button[BtnSticky]->setPixmaps(P_PINUP);
00429 button[BtnSticky]->setToggle();
00430 button[BtnSticky]->setDown(isOnAllDesktops());
00431 connect(button[BtnSticky], SIGNAL(clicked()),
00432
this, SLOT(toggleOnAllDesktops()));
00433 titleLayout->addWidget(button[BtnSticky]);
00434 }
00435
break;
00436
case 'H':
00437
if (
providesContextHelp() && (!button[BtnHelp])) {
00438 button[BtnHelp] =
new B2Button(
this, tb, tips[BtnHelp]);
00439 button[BtnHelp]->setPixmaps(P_HELP);
00440 connect(button[BtnHelp], SIGNAL(clicked()),
00441
this, SLOT(
showContextHelp()));
00442 titleLayout->addWidget(button[BtnHelp]);
00443 }
00444
break;
00445
case 'I':
00446
if (isMinimizable() && (!button[BtnIconify])) {
00447 button[BtnIconify] =
new B2Button(
this, tb,tips[BtnIconify]);
00448 button[BtnIconify]->setPixmaps(P_ICONIFY);
00449 connect(button[BtnIconify], SIGNAL(clicked()),
00450
this, SLOT(
minimize()));
00451 titleLayout->addWidget(button[BtnIconify]);
00452 }
00453
break;
00454
case 'A':
00455
if (isMaximizable() && (!button[BtnMax])) {
00456 button[BtnMax] =
new B2Button(
this, tb, tips[BtnMax],
00457 LeftButton | MidButton | RightButton);
00458 button[BtnMax]->setPixmaps(maximizeMode() == MaximizeFull ?
00459 P_NORMALIZE : P_MAX);
00460 connect(button[BtnMax], SIGNAL(clicked()),
00461
this, SLOT(maxButtonClicked()));
00462 titleLayout->addWidget(button[BtnMax]);
00463 }
00464
break;
00465
case 'X':
00466
if (isCloseable() && !button[BtnClose]) {
00467 button[BtnClose] =
new B2Button(
this, tb, tips[BtnClose]);
00468 button[BtnClose]->setPixmaps(P_CLOSE);
00469 connect(button[BtnClose], SIGNAL(clicked()),
00470
this, SLOT(
closeWindow()));
00471 titleLayout->addWidget(button[BtnClose]);
00472 }
00473
break;
00474
case 'L':
00475
if (isShadeable() && !button[BtnShade]) {
00476 button[BtnShade] =
new B2Button(
this, tb, tips[BtnShade]);
00477 button[BtnShade]->setPixmaps(P_SHADE);
00478 connect(button[BtnShade], SIGNAL(clicked()),
00479
this, SLOT(shadeButtonClicked()));
00480 titleLayout->addWidget(button[BtnShade]);
00481 }
00482
break;
00483
case 'R':
00484
if (
isResizable() && !button[BtnResize]) {
00485 button[BtnResize] =
new B2Button(
this, tb, tips[BtnResize]);
00486 button[BtnResize]->setPixmaps(P_RESIZE);
00487 connect(button[BtnResize], SIGNAL(pressed()),
00488
this, SLOT(resizeButtonPressed()));
00489 titleLayout->addWidget(button[BtnResize]);
00490 }
00491
break;
00492
case '_':
00493 titleLayout->addSpacing(4);
00494
break;
00495 }
00496 }
00497 }
00498
00499
bool B2Client::mustDrawHandle()
const
00500
{
00501
bool drawSmallBorders = !options()->moveResizeMaximizedWindows();
00502
if (drawSmallBorders && (maximizeMode() &
MaximizeVertical)) {
00503
return false;
00504 }
else {
00505
return draw_handle &&
isResizable();
00506 }
00507 }
00508
00509
void B2Client::iconChange()
00510 {
00511
if (button[BtnMenu])
00512 button[BtnMenu]->repaint(
false);
00513 }
00514
00515
00516
00517
void B2Client::calcHiddenButtons()
00518 {
00519
00520
00521 B2Button* btnArray[] = {
00522 button[BtnShade], button[BtnSticky], button[BtnHelp], button[BtnResize],
00523 button[BtnMax], button[BtnIconify], button[BtnClose], button[BtnMenu]
00524 };
00525
int minWidth = 120;
00526
int currentWidth = width();
00527
int count = 0;
00528
int i;
00529
00530
00531
while (currentWidth < minWidth) {
00532 currentWidth += buttonSize + 1;
00533 count++;
00534 }
00535
00536
if (count > BtnCount) count = BtnCount;
00537
00538
00539
for (i = 0; i < count; i++) {
00540
if (btnArray[i] && btnArray[i]->isVisible())
00541 btnArray[i]->hide();
00542 }
00543
00544
for (i = count; i < BtnCount; i++) {
00545
if (btnArray[i] && (!btnArray[i]->isVisible()))
00546 btnArray[i]->show();
00547 }
00548 }
00549
00550
void B2Client::resizeEvent(QResizeEvent * )
00551 {
00552 calcHiddenButtons();
00553 titlebar->layout()->activate();
00554 positionButtons();
00555
00556
00557
00558 titleMoveAbs(bar_x_ofs);
00559 doShape();
00560
00561 widget()->repaint();
00562 }
00563
00564
void B2Client::captionChange()
00565 {
00566 positionButtons();
00567 titleMoveAbs(bar_x_ofs);
00568 doShape();
00569 titlebar->recalcBuffer();
00570 titlebar->repaint(
false);
00571 }
00572
00573
void B2Client::paintEvent(QPaintEvent* e)
00574 {
00575 QPainter p(widget());
00576
00577
KDecoration::ColorType frameColorGroup = colored_frame ?
00578
KDecoration::ColorTitleBar :
KDecoration::ColorFrame;
00579
00580 QRect t = titlebar->geometry();
00581
00582
00583
int fHeight = height() - t.height();
00584
00585
00586
int bb = mustDrawHandle() ? 4 : 0;
00587
int bDepth = thickness + bb;
00588
00589 QColorGroup fillColor = options()->colorGroup(frameColorGroup, isActive());
00590 QBrush fillBrush(options()->color(frameColorGroup, isActive()));
00591
00592
00593 p.drawRect(0, t.bottom() - thickness + 1,
00594 width(), fHeight - bb + thickness);
00595
00596
if (thickness >= 2) {
00597
00598 p.drawRect(thickness - 1, t.bottom(),
00599 width() - 2 * (thickness - 1), fHeight - bDepth + 2);
00600
00601
if (thickness >= 3) {
00602
00603 qDrawShadePanel(&p, 1, t.bottom() - thickness + 2,
00604 width() - 2, fHeight - 2 - bb + thickness, fillColor,
false);
00605
if (thickness == 4) {
00606 p.setPen(fillColor.background());
00607 p.drawRect(thickness - 2, t.bottom() - 1,
00608 width() - 2 * (thickness - 2), fHeight + 4 - bDepth);
00609 }
else if (thickness > 4) {
00610 qDrawShadePanel(&p, thickness - 2,
00611 t.bottom() - 1, width() - 2 * (thickness - 2),
00612 fHeight + 4 - bDepth, fillColor,
true);
00613
if (thickness >= 5) {
00614
00615 p.fillRect(2, t.bottom() - thickness + 3,
00616 width() - 4, thickness - 4, fillBrush);
00617 p.fillRect(2, height() - bDepth + 2,
00618 width() - 4, thickness - 4, fillBrush);
00619 p.fillRect(2, t.bottom() - 1,
00620 thickness - 4, fHeight - bDepth + 4, fillBrush);
00621 p.fillRect(width() - thickness + 2, t.bottom() - 1,
00622 thickness - 4, fHeight - bDepth + 4, fillBrush);
00623 }
00624 }
00625 }
00626 }
00627
00628
00629
if (mustDrawHandle()) {
00630 p.setPen(Qt::black);
00631
int hx = width() - 40;
00632
int hw = 40;
00633
00634 p.drawLine(width() - 1, height() - thickness - 4,
00635 width() - 1, height() - 1);
00636 p.drawLine(hx, height() - 1, width() - 1, height() - 1);
00637 p.drawLine(hx, height() - 4, hx, height() - 1);
00638
00639 p.fillRect(hx + 1, height() - thickness - 3,
00640 hw - 2, thickness + 2, fillBrush);
00641
00642 p.setPen(fillColor.dark());
00643 p.drawLine(width() - 2, height() - thickness - 4,
00644 width() - 2, height() - 2);
00645 p.drawLine(hx + 1, height() - 2, width() - 2, height() - 2);
00646
00647 p.setPen(fillColor.light());
00648 p.drawLine(hx + 1, height() - thickness - 2,
00649 hx + 1, height() - 3);
00650 p.drawLine(hx + 1, height() - thickness - 3,
00651 width() - 3, height() - thickness - 3);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
if (titlebar->isFullyObscured()) {
00664
00665 QRegion reg(QRect(0, 0, width(), buttonSize + 4));
00666 reg = reg.intersect(e->region());
00667
if (!reg.isEmpty())
00668 unobscureTitlebar();
00669 }
00670 }
00671
00672
#define QCOORDARRLEN(x) sizeof(x) / (sizeof(QCOORD) * 2)
00673
00674
void B2Client::doShape()
00675 {
00676 QRect t = titlebar->geometry();
00677 QRegion mask(widget()->rect());
00678
00679
if (bar_x_ofs) {
00680 mask -= QRect(0, 0, bar_x_ofs, t.height() - thickness);
00681 mask -= QRect(0, t.height() - thickness, 1, 1);
00682 }
00683
if (t.right() < width() - 1) {
00684 mask -= QRect(width() - 1,
00685 t.height() - thickness, 1, 1);
00686 mask -= QRect(t.right() + 1, 0,
00687 width() - t.right() - 1, t.height() - thickness);
00688 }
00689 mask -= QRect(width() - 1, height() - 1, 1, 1);
00690
if (mustDrawHandle()) {
00691 mask -= QRect(0, height() - 5, 1, 1);
00692 mask -= QRect(width() - 1, height() - 1, 1, 1);
00693 mask -= QRect(width() - 40, height() - 1, 1, 1);
00694 mask -= QRect(0, height() - 4, width() - 40, 4);
00695 }
else {
00696 mask -= QRect(0, height() - 1, 1, 1);
00697 }
00698
00699 setMask(mask);
00700 }
00701
00702
void B2Client::showEvent(QShowEvent *)
00703 {
00704 calcHiddenButtons();
00705 positionButtons();
00706 doShape();
00707 widget()->repaint();
00708 titlebar->repaint(
false);
00709 }
00710
00711
KDecoration::Position B2Client::mousePosition(
const QPoint& p)
const
00712
{
00713
const int range = 16;
00714 QRect t = titlebar->geometry();
00715 t.setHeight(buttonSize + 4 - thickness);
00716
int ly = t.bottom();
00717
int lx = t.right();
00718
int bb = mustDrawHandle() ? 0 : 5;
00719
00720
if (p.x() > t.right()) {
00721
if (p.y() <= ly + range && p.x() >= width() - range)
00722
return PositionTopRight;
00723
else if (p.y() <= ly + thickness)
00724
return PositionTop;
00725 }
else if (p.x() < bar_x_ofs) {
00726
if (p.y() <= ly + range && p.x() <= range)
00727
return PositionTopLeft;
00728
else if (p.y() <= ly + thickness)
00729
return PositionTop;
00730 }
else if (p.y() < ly) {
00731
if (p.x() > bar_x_ofs + thickness &&
00732 p.x() < lx - thickness && p.y() > thickness)
00733
return KDecoration::mousePosition(p);
00734
if (p.x() > bar_x_ofs + range && p.x() < lx - range)
00735
return PositionTop;
00736
if (p.y() <= range) {
00737
if (p.x() <= bar_x_ofs + range)
00738
return PositionTopLeft;
00739
else return PositionTopRight;
00740 }
else {
00741
if (p.x() <= bar_x_ofs + range)
00742
return PositionLeft;
00743
else return PositionRight;
00744 }
00745 }
00746
00747
if (p.y() >= height() - 8 + bb) {
00748
00749
if (p.x() <= range)
return PositionBottomLeft;
00750
if (p.x() >= width() - range)
return PositionBottomRight;
00751
return PositionBottom;
00752 }
00753
00754
return KDecoration::mousePosition(p);
00755 }
00756
00757
void B2Client::titleMoveAbs(
int new_ofs)
00758 {
00759
if (new_ofs < 0) new_ofs = 0;
00760
if (new_ofs + titlebar->width() > width()) {
00761 new_ofs = width() - titlebar->width();
00762 }
00763
if (bar_x_ofs != new_ofs) {
00764 bar_x_ofs = new_ofs;
00765 positionButtons();
00766 doShape();
00767 widget()->repaint(0, 0, width(), buttonSize + 4,
false);
00768 titlebar->repaint(
false);
00769 }
00770 }
00771
00772
void B2Client::titleMoveRel(
int xdiff)
00773 {
00774 titleMoveAbs(bar_x_ofs + xdiff);
00775 }
00776
00777
void B2Client::desktopChange()
00778 {
00779
bool on = isOnAllDesktops();
00780
if (B2Button *b = button[BtnSticky]) {
00781 b->setDown(on);
00782 QToolTip::remove(b);
00783 QToolTip::add(b,
00784 on ? i18n(
"Not on all desktops") : i18n(
"On all desktops"));
00785 }
00786 }
00787
00788
void B2Client::maximizeChange()
00789 {
00790
bool m = maximizeMode() ==
MaximizeFull;
00791
if (button[BtnMax]) {
00792 button[BtnMax]->setPixmaps(m ? P_NORMALIZE : P_MAX);
00793 button[BtnMax]->repaint();
00794 QToolTip::remove(button[BtnMax]);
00795 QToolTip::add(button[BtnMax],
00796 m ? i18n(
"Restore") : i18n(
"Maximize"));
00797 }
00798 spacer->changeSize(10, thickness + (mustDrawHandle() ? 4 : 0),
00799 QSizePolicy::Expanding, QSizePolicy::Minimum);
00800
00801 g->activate();
00802 doShape();
00803 widget()->repaint(
false);
00804 }
00805
00806
void B2Client::activeChange()
00807 {
00808 widget()->repaint(
false);
00809 titlebar->repaint(
false);
00810
00811 QColor c = options()->colorGroup(
00812 KDecoration::ColorTitleBar, isActive()).color(QColorGroup::Button);
00813
00814
for (
int i = 0; i < BtnCount; i++)
00815
if (button[i]) {
00816 button[i]->setBg(c);
00817 button[i]->repaint(
false);
00818 }
00819 }
00820
00821
void B2Client::shadeChange()
00822 {
00823 spacer->changeSize(10, thickness + (mustDrawHandle() ? 4 : 0),
00824 QSizePolicy::Expanding, QSizePolicy::Minimum);
00825 g->activate();
00826 doShape();
00827
if (B2Button *b = button[BtnShade]) {
00828 QToolTip::remove(b);
00829 QToolTip::add(b, isShade() ? i18n(
"Unshade") : i18n(
"Shade"));
00830 }
00831 }
00832
00833 QSize B2Client::minimumSize()
const
00834
{
00835
int left, right, top, bottom;
00836 borders(left, right, top, bottom);
00837
return QSize(left + right + 2 * buttonSize, top + bottom);
00838 }
00839
00840
void B2Client::resize(
const QSize& s)
00841 {
00842 widget()->resize(s);
00843 }
00844
00845
void B2Client::borders(
int &left,
int &right,
int &top,
int &bottom)
const
00846
{
00847 left = right = thickness;
00848 top = buttonSize + 4;
00849 bottom = thickness + (mustDrawHandle() ? 4 : 0);
00850 }
00851
00852
void B2Client::menuButtonPressed()
00853 {
00854
static B2Client *lastClient = NULL;
00855
00856
bool dbl = (lastClient ==
this &&
00857 time.elapsed() <= QApplication::doubleClickInterval());
00858 lastClient =
this;
00859 time.start();
00860
if (!dbl) {
00861 KDecorationFactory* f = factory();
00862 QRect menuRect = button[BtnMenu]->rect();
00863 QPoint menuTop = button[BtnMenu]->mapToGlobal(menuRect.topLeft());
00864 QPoint menuBottom = button[BtnMenu]->mapToGlobal(menuRect.bottomRight());
00865 showWindowMenu(QRect(menuTop, menuBottom));
00866
if (!f->exists(
this))
00867
return;
00868 button[BtnMenu]->setDown(
false);
00869 }
else {
00870
switch (menu_dbl_click_op) {
00871
case B2::MinimizeOp:
00872
minimize();
00873
break;
00874
case B2::ShadeOp:
00875 setShade(!isShade());
00876
break;
00877
case B2::CloseOp:
00878
closeWindow();
00879
break;
00880
case B2::NoOp:
00881
default:
00882
break;
00883 }
00884 }
00885 }
00886
00887
void B2Client::unobscureTitlebar()
00888 {
00889
00890
00891
00892
00893
if (in_unobs) {
00894
return;
00895 }
00896 in_unobs = 1;
00897 QRegion reg(QRect(0,0,width(), buttonSize + 4));
00898 reg = unobscuredRegion(reg);
00899
if (!reg.isEmpty()) {
00900
00901
00902
00903
00904 titleMoveAbs(reg.boundingRect().x());
00905 }
00906 in_unobs = 0;
00907 }
00908
00909
static void redraw_pixmaps()
00910 {
00911
int i;
00912 QColorGroup aGrp = options()->colorGroup(KDecoration::ColorButtonBg,
true);
00913 QColorGroup iGrp = options()->colorGroup(KDecoration::ColorButtonBg,
false);
00914
00915
00916 drawB2Rect(PIXMAP_A(P_CLOSE), aGrp.button(),
false);
00917 drawB2Rect(PIXMAP_AH(P_CLOSE), aGrp.button(),
true);
00918 drawB2Rect(PIXMAP_AD(P_CLOSE), aGrp.button(),
true);
00919
00920 drawB2Rect(PIXMAP_I(P_CLOSE), iGrp.button(),
false);
00921 drawB2Rect(PIXMAP_IH(P_CLOSE), iGrp.button(),
true);
00922 drawB2Rect(PIXMAP_ID(P_CLOSE), iGrp.button(),
true);
00923
00924
00925 KPixmap thinBox;
00926 thinBox.resize(buttonSize - 2, 6);
00927
for (i = 0; i < NumStates; i++) {
00928
bool is_act = (i < 2);
00929
bool is_down = ((i & 1) == 1);
00930 KPixmap *pix = pixmap[P_SHADE * NumStates + i];
00931 QColor color = is_act ? aGrp.button() : iGrp.button();
00932 drawB2Rect(&thinBox, color, is_down);
00933 pix->fill(Qt::black);
00934 bitBlt(pix, 0, 0, &thinBox,
00935 0, 0, thinBox.width(), thinBox.height(), Qt::CopyROP,
true);
00936 }
00937
00938
00939
for (i = 0; i < NumStates; i++) {
00940 *pixmap[P_MAX * NumStates + i] = *pixmap[P_CLOSE * NumStates + i];
00941 pixmap[P_MAX * NumStates + i]->detach();
00942 }
00943
00944
00945 KPixmap smallBox;
00946 smallBox.resize(10, 10);
00947 KPixmap largeBox;
00948 largeBox.resize(12, 12);
00949
00950
for (i = 0; i < NumStates; i++) {
00951
bool is_act = (i < 3);
00952
bool is_down = (i == Down || i == IDown);
00953 KPixmap *pix = pixmap[P_NORMALIZE * NumStates + i];
00954 drawB2Rect(&smallBox, is_act ? aGrp.button() : iGrp.button(), is_down);
00955 drawB2Rect(&largeBox, is_act ? aGrp.button() : iGrp.button(), is_down);
00956 pix->fill(options()->color(KDecoration::ColorTitleBar, is_act));
00957 bitBlt(pix, pix->width() - 12, pix->width() - 12, &largeBox,
00958 0, 0, 12, 12, Qt::CopyROP,
true);
00959 bitBlt(pix, 0, 0, &smallBox, 0, 0, 10, 10, Qt::CopyROP,
true);
00960
00961 bitBlt(pixmap[P_ICONIFY * NumStates + i], 0, 0,
00962 &smallBox, 0, 0, 10, 10, Qt::CopyROP,
true);
00963 }
00964
00965
00966
for (i = 0; i < NumStates; i++) {
00967
bool is_act = (i < 3);
00968
bool is_down = (i == Down || i == IDown);
00969 *pixmap[P_RESIZE * NumStates + i] = *pixmap[P_CLOSE * NumStates + i];
00970 pixmap[P_RESIZE * NumStates + i]->detach();
00971 drawB2Rect(&smallBox, is_act ? aGrp.button() : iGrp.button(), is_down);
00972 bitBlt(pixmap[P_RESIZE * NumStates + i],
00973 0, 0, &smallBox, 0, 0, 10, 10, Qt::CopyROP,
true);
00974 }
00975
00976
00977 QPainter p;
00978
00979
for (
int j = 0; j < 3; j++) {
00980
int pix;
00981
unsigned const char *light, *dark;
00982
switch (j) {
00983
case 0:
00984 pix = P_CLOSE; light = close_white_bits; dark = close_dgray_bits;
00985
break;
00986
case 1:
00987 pix = P_MENU; light = menu_white_bits; dark = menu_dgray_bits;
00988
break;
00989
default:
00990 pix = P_HELP; light = help_light_bits; dark = help_dark_bits;
00991
break;
00992 }
00993
int off = (pixmap[pix * NumStates]->width() - 16) / 2;
00994
for (i = 0; i < NumStates; i++) {
00995 p.begin(pixmap[pix * NumStates + i]);
00996 kColorBitmaps(&p, (i < 3) ? aGrp : iGrp, off, off, 16, 16,
true,
00997 light, NULL, NULL, dark, NULL, NULL);
00998 p.end();
00999 }
01000 }
01001
01002
01003
for (i = 0; i < NumStates; i++) {
01004
bool isDown = (i == Down || i == IDown);
01005
unsigned const char *white = isDown ? pindown_white_bits : pinup_white_bits;
01006
unsigned const char *gray = isDown ? pindown_gray_bits : pinup_gray_bits;
01007
unsigned const char *dgray =isDown ? pindown_dgray_bits : pinup_dgray_bits;
01008 p.begin(pixmap[P_PINUP * NumStates + i]);
01009 kColorBitmaps(&p, (i < 3) ? aGrp : iGrp, 0, 0, 16, 16,
true, white,
01010 gray, NULL, dgray, NULL, NULL);
01011 p.end();
01012 }
01013
01014
01015 KIconEffect ie;
01016 QPixmap hilighted;
01017
for (i = 0; i < P_NUM_BUTTON_TYPES; i++) {
01018
int offset = i * NumStates;
01019 hilighted = ie.apply(*pixmap[offset + Norm],
01020 KIcon::Small, KIcon::ActiveState);
01021 *pixmap[offset + Hover] = hilighted;
01022
01023 hilighted = ie.apply(*pixmap[offset + INorm],
01024 KIcon::Small, KIcon::ActiveState);
01025 *pixmap[offset + IHover] = hilighted;
01026 }
01027
01028
01029
01030
if (QPixmap::defaultDepth() > 8) {
01031 QColor titleColor[4] = {
01032 options()->color(KDecoration::ColorTitleBar,
true),
01033 options()->color(KDecoration::ColorFrame,
true),
01034
01035 options()->color(KDecoration::ColorTitleBlend,
false),
01036 options()->color(KDecoration::ColorTitleBar,
false)
01037 };
01038
01039
if (colored_frame) {
01040 titleColor[0] = options()->color(KDecoration::ColorTitleBlend,
true);
01041 titleColor[1] = options()->color(KDecoration::ColorTitleBar,
true);
01042 }
01043
01044
for (i = 0; i < 2; i++) {
01045
if (titleColor[2 * i] != titleColor[2 * i + 1]) {
01046
if (!titleGradient[i]) {
01047 titleGradient[i] =
new KPixmap;
01048 }
01049 titleGradient[i]->resize(64, buttonSize + 3);
01050 KPixmapEffect::gradient(*titleGradient[i],
01051 titleColor[2 * i], titleColor[2 * i + 1],
01052 KPixmapEffect::VerticalGradient);
01053 }
else {
01054
delete titleGradient[i];
01055 titleGradient[i] = 0;
01056 }
01057 }
01058 }
01059 }
01060
01061
void B2Client::positionButtons()
01062 {
01063 QFontMetrics fm(options()->font(isActive()));
01064 QString cap =
caption();
01065
if (cap.length() < 5)
01066 cap =
"XXXXX";
01067
int textLen = fm.width(cap);
01068
01069 QRect t = titlebar->captionSpacer->geometry();
01070
int titleWidth = titlebar->width() - t.width() + textLen + 2;
01071
if (titleWidth > width()) titleWidth = width();
01072
01073 titlebar->resize(titleWidth, buttonSize + 4);
01074 titlebar->move(bar_x_ofs, 0);
01075 }
01076
01077
01078
01079
static QRect *visible_bound;
01080
static QPointArray bound_shape;
01081
01082
bool B2Client::drawbound(
const QRect& geom,
bool clear)
01083 {
01084
if (clear) {
01085
if (!visible_bound)
return true;
01086 }
01087
01088
if (!visible_bound) {
01089 visible_bound =
new QRect(geom);
01090 QRect t = titlebar->geometry();
01091
int frameTop = geom.top() + t.bottom();
01092
int barLeft = geom.left() + bar_x_ofs;
01093
int barRight = barLeft + t.width() - 1;
01094
if (barRight > geom.right()) barRight = geom.right();
01095
01096 bound_shape.putPoints(0, 8,
01097 geom.left(), frameTop,
01098 barLeft, frameTop,
01099 barLeft, geom.top(),
01100 barRight, geom.top(),
01101 barRight, frameTop,
01102 geom.right(), frameTop,
01103 geom.right(), geom.bottom(),
01104 geom.left(), geom.bottom());
01105 }
else {
01106 *visible_bound = geom;
01107 }
01108 QPainter p(workspaceWidget());
01109 p.setPen(QPen(Qt::white, 5));
01110 p.setRasterOp(Qt::XorROP);
01111 p.drawPolygon(bound_shape);
01112
01113
if (clear) {
01114
delete visible_bound;
01115 visible_bound = 0;
01116 }
01117
return true;
01118 }
01119
01120
bool B2Client::eventFilter(QObject *o, QEvent *e)
01121 {
01122
if (o != widget())
01123
return false;
01124
switch (e->type()) {
01125
case QEvent::Resize:
01126 resizeEvent(static_cast< QResizeEvent* >(e));
01127
return true;
01128
case QEvent::Paint:
01129 paintEvent(static_cast< QPaintEvent* >(e));
01130
return true;
01131
case QEvent::MouseButtonDblClick:
01132 titlebar->mouseDoubleClickEvent(static_cast< QMouseEvent* >(e));
01133
return true;
01134
case QEvent::MouseButtonPress:
01135 processMousePressEvent(static_cast< QMouseEvent* >(e));
01136
return true;
01137
case QEvent::Show:
01138 showEvent(static_cast< QShowEvent* >(e));
01139
return true;
01140
default:
01141
break;
01142 }
01143
return false;
01144 }
01145
01146
01147
01148 B2Button::B2Button(B2Client *_client, QWidget *parent,
01149
const QString& tip,
const int realizeBtns)
01150 : QButton(parent, 0), hover(false)
01151 {
01152 setBackgroundMode(NoBackground);
01153 setCursor(arrowCursor);
01154 realizeButtons = realizeBtns;
01155 client = _client;
01156 useMiniIcon =
false;
01157 setFixedSize(buttonSize, buttonSize);
01158 QToolTip::add(
this, tip);
01159 }
01160
01161
01162 QSize B2Button::sizeHint()
const
01163
{
01164
return QSize(buttonSize, buttonSize);
01165 }
01166
01167 QSizePolicy B2Button::sizePolicy()
const
01168
{
01169
return(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
01170 }
01171
01172
void B2Button::drawButton(QPainter *p)
01173 {
01174 KPixmap* gradient = titleGradient[client->isActive() ? 0 : 1];
01175
if (gradient) {
01176 p->drawTiledPixmap(0, 0, buttonSize, buttonSize, *gradient, 0, 2);
01177 }
else {
01178 p->fillRect(rect(), bg);
01179 }
01180
if (useMiniIcon) {
01181 QPixmap miniIcon = client->icon().pixmap(QIconSet::Small,
01182 client->isActive() ? QIconSet::Normal : QIconSet::Disabled);
01183 p->drawPixmap((width() - miniIcon.width()) / 2,
01184 (height() - miniIcon.height()) / 2, miniIcon);
01185 }
else {
01186
int type;
01187
if (client->isActive()) {
01188
if (isOn() || isDown())
01189 type = Down;
01190
else if (hover)
01191 type = Hover;
01192
else
01193 type = Norm;
01194 }
else {
01195
if (isOn() || isDown())
01196 type = IDown;
01197
else if (hover)
01198 type = IHover;
01199
else
01200 type = INorm;
01201 }
01202 p->drawPixmap((width() - icon[type]->width()) / 2,
01203 (height() - icon[type]->height()) / 2, *icon[type]);
01204 }
01205 }
01206
01207
void B2Button::setPixmaps(
int button_id)
01208 {
01209 button_id *= NumStates;
01210
for (
int i = 0; i < NumStates; i++) {
01211 icon[i] = B2::pixmap[button_id + i];
01212 }
01213 repaint(
false);
01214 }
01215
01216
void B2Button::mousePressEvent(QMouseEvent * e)
01217 {
01218 last_button = e->button();
01219 QMouseEvent me(e->type(), e->pos(), e->globalPos(),
01220 (e->button() & realizeButtons) ? LeftButton : NoButton,
01221 e->state());
01222 QButton::mousePressEvent(&me);
01223 }
01224
01225
void B2Button::mouseReleaseEvent(QMouseEvent * e)
01226 {
01227 last_button = e->button();
01228 QMouseEvent me(e->type(), e->pos(), e->globalPos(),
01229 (e->button() & realizeButtons) ? LeftButton : NoButton,
01230 e->state());
01231 QButton::mouseReleaseEvent(&me);
01232 }
01233
01234
void B2Button::enterEvent(QEvent *e)
01235 {
01236 hover =
true;
01237 repaint(
false);
01238 QButton::enterEvent(e);
01239 }
01240
01241
void B2Button::leaveEvent(QEvent *e)
01242 {
01243 hover =
false;
01244 repaint(
false);
01245 QButton::leaveEvent(e);
01246 }
01247
01248
01249
01250 B2Titlebar::B2Titlebar(B2Client *parent)
01251 : QWidget(parent->widget(), 0, WStyle_Customize | WRepaintNoErase),
01252 client(parent),
01253 set_x11mask(false), isfullyobscured(false), shift_move(false)
01254 {
01255 setBackgroundMode(NoBackground);
01256 captionSpacer =
new QSpacerItem(buttonSize, buttonSize + 4,
01257 QSizePolicy::Expanding, QSizePolicy::Fixed);
01258 }
01259
01260
bool B2Titlebar::x11Event(XEvent *e)
01261 {
01262
if (!set_x11mask) {
01263 set_x11mask =
true;
01264 XSelectInput(qt_xdisplay(), winId(),
01265 KeyPressMask | KeyReleaseMask |
01266 ButtonPressMask | ButtonReleaseMask |
01267 KeymapStateMask |
01268 ButtonMotionMask |
01269 EnterWindowMask | LeaveWindowMask |
01270 FocusChangeMask |
01271 ExposureMask |
01272 PropertyChangeMask |
01273 StructureNotifyMask | SubstructureRedirectMask |
01274 VisibilityChangeMask);
01275 }
01276
switch (e->type) {
01277
case VisibilityNotify:
01278 isfullyobscured =
false;
01279
if (e->xvisibility.state == VisibilityFullyObscured) {
01280 isfullyobscured =
true;
01281 client->unobscureTitlebar();
01282 }
01283
break;
01284
default:
01285
break;
01286 }
01287
return QWidget::x11Event(e);
01288 }
01289
01290
void B2Titlebar::drawTitlebar(QPainter &p,
bool state)
01291 {
01292 KPixmap* gradient = titleGradient[state ? 0 : 1];
01293
01294 QRect t = rect();
01295
01296 p.setPen(Qt::black);
01297 p.drawLine(0, 0, 0, t.bottom());
01298 p.drawLine(0, 0, t.right(), 0);
01299 p.drawLine(t.right(), 0, t.right(), t.bottom());
01300
01301
01302
const QColorGroup cg =
01303 options()->colorGroup(KDecoration::ColorTitleBar, state);
01304 QBrush brush(cg.background());
01305
if (gradient) brush.setPixmap(*gradient);
01306 qDrawShadeRect(&p, 1, 1, t.right() - 1, t.height() - 1,
01307 cg,
false, 1, 0, &brush);
01308
01309
01310 p.setPen(options()->color(KDecoration::ColorFont, state));
01311 p.setFont(options()->font(state));
01312 t = captionSpacer->geometry();
01313 p.drawText(t, AlignLeft | AlignVCenter, client->caption());
01314 }
01315
01316
void B2Titlebar::recalcBuffer()
01317 {
01318 titleBuffer.resize(width(), height());
01319
01320 QPainter p(&titleBuffer);
01321 drawTitlebar(p,
true);
01322 oldTitle =
caption();
01323 }
01324
01325
void B2Titlebar::resizeEvent(QResizeEvent *)
01326 {
01327 recalcBuffer();
01328 repaint(
false);
01329 }
01330
01331
01332
void B2Titlebar::paintEvent(QPaintEvent *)
01333 {
01334
if(client->isActive())
01335 bitBlt(
this, 0, 0, &titleBuffer, 0, 0, titleBuffer.width(),
01336 titleBuffer.height(), Qt::CopyROP,
true);
01337
else {
01338 QPainter p(
this);
01339 drawTitlebar(p,
false);
01340 }
01341 }
01342
01343
void B2Titlebar::mouseDoubleClickEvent(QMouseEvent *e)
01344 {
01345
if (e->y() < height()) {
01346 client->titlebarDblClickOperation();
01347 }
01348 }
01349
01350
void B2Titlebar::mousePressEvent(QMouseEvent * e)
01351 {
01352 shift_move = e->state() & ShiftButton;
01353
if (shift_move) {
01354 moveOffset = e->globalPos();
01355 }
else {
01356 e->ignore();
01357 }
01358 }
01359
01360
void B2Titlebar::mouseReleaseEvent(QMouseEvent * e)
01361 {
01362
if (shift_move) shift_move =
false;
01363
else e->ignore();
01364 }
01365
01366
void B2Titlebar::mouseMoveEvent(QMouseEvent * e)
01367 {
01368
if (shift_move) {
01369
int oldx = mapFromGlobal(moveOffset).x();
01370
int xdiff = e->globalPos().x() - moveOffset.x();
01371 moveOffset = e->globalPos();
01372
if (oldx >= 0 && oldx <= rect().right()) {
01373 client->titleMoveRel(xdiff);
01374 }
01375 }
else {
01376 e->ignore();
01377 }
01378 }
01379
01380 }
01381
01382
#include "b2client.moc"
01383
01384
01385