summaryrefslogtreecommitdiff
path: root/library/qpedecoration_qws.cpp
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /library/qpedecoration_qws.cpp
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'library/qpedecoration_qws.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/qpedecoration_qws.cpp639
1 files changed, 639 insertions, 0 deletions
diff --git a/library/qpedecoration_qws.cpp b/library/qpedecoration_qws.cpp
new file mode 100644
index 0000000..b6085ef
--- a/dev/null
+++ b/library/qpedecoration_qws.cpp
@@ -0,0 +1,639 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include <qapplication.h>
21#include <qstyle.h>
22#include <qwidget.h>
23#include <qpainter.h>
24#include <qtimer.h>
25#include <qwhatsthis.h>
26#include "qcopenvelope_qws.h"
27#include "qpedecoration_qws.h"
28#include <qdialog.h>
29#include <qdrawutil.h>
30#include <qgfx_qws.h>
31#include "qpeapplication.h"
32#include "resource.h"
33#include "global.h"
34#include <qfile.h>
35#include <qsignal.h>
36
37#include <stdlib.h>
38
39extern QRect qt_maxWindowRect;
40
41//#define MINIMIZE_HELP_HACK // use minimize button when not a dialog
42
43//#define WHATSTHIS_MODE
44
45#ifndef QT_NO_QWS_QPE_WM_STYLE
46
47#ifndef QT_NO_IMAGEIO_XPM
48
49/* XPM */
50static const char * const qpe_close_xpm[] = {
51"16 16 3 1",
52" c None",
53". c #FFFFFF",
54"+ c #000000",
55" ",
56" ",
57" ..... ",
58" ..+++++.. ",
59" .+++++++++. ",
60" .+..+++..+. ",
61" .++...+...++. ",
62" .+++.....+++. ",
63" .++++...++++. ",
64" .+++.....+++. ",
65" .++...+...++. ",
66" .+..+++..+. ",
67" .+++++++++. ",
68" ..+++++.. ",
69" ..... ",
70" "};
71
72/* XPM */
73static const char * const qpe_accept_xpm[] = {
74"16 16 3 1",
75" c None",
76". c #FFFFFF",
77"+ c #000000",
78" ",
79" ",
80" ..... ",
81" ..+++++.. ",
82" .+++++++++. ",
83" .+++++++++. ",
84" .+++++++..++. ",
85" .++.+++...++. ",
86" .+...+...+++. ",
87" .+......++++. ",
88" .++....+++++. ",
89" .++..+++++. ",
90" .+++++++++. ",
91" ..+++++.. ",
92" ..... ",
93" "};
94
95#endif // QT_NO_IMAGEIO_XPM
96
97class TLWidget : public QWidget
98{
99public:
100 QWSManager *manager()
101 {
102 return topData()->qwsManager;
103 }
104
105 QTLWExtra *topExtra()
106 {
107 return topData();
108 }
109};
110
111QPEManager::QPEManager( QPEDecoration *d, QObject *parent )
112 : QObject( parent ), decoration( d ), helpState(0)
113{
114 wtTimer = new QTimer( this );
115 connect( wtTimer, SIGNAL(timeout()), this, SLOT(whatsThisTimeout()) );
116}
117
118
119void QPEManager::updateActive()
120{
121 QWidget *newActive = qApp->activeWindow();
122 if ( (QWidget*)active == newActive )
123 return;
124
125 if ( active ) {
126 ((TLWidget *)(QWidget*)active)->manager()->removeEventFilter( this );
127 }
128
129 if ( newActive && ((TLWidget *)newActive)->manager() ) {
130 active = newActive;
131 ((TLWidget *)(QWidget*)active)->manager()->installEventFilter( this );
132 } else {
133 active = 0;
134 }
135}
136
137int QPEManager::pointInQpeRegion( QWidget *w, const QPoint &p )
138{
139 if ( decoration->region( w, w->geometry(),
140 (QWSDecoration::Region)QPEDecoration::Help ).contains(p) ) {
141 return QPEDecoration::Help;
142 }
143
144 return QWSDecoration::None;
145}
146
147bool QPEManager::eventFilter( QObject *o, QEvent *e )
148{
149 QWSManager *mgr = (QWSManager *)o;
150 QWidget *w = mgr->widget();
151 switch ( e->type() ) {
152 case QEvent::MouseButtonPress:
153 {
154 if ( QWhatsThis::inWhatsThisMode() ) {
155 QWhatsThis::leaveWhatsThisMode();
156 return true;
157 }
158 pressTime = QTime::currentTime();
159 QPoint p = ((QMouseEvent*)e)->globalPos();
160 if ( pointInQpeRegion( w, p ) == QPEDecoration::Help ) {
161 helpState = QWSButton::Clicked|QWSButton::MouseOver;
162 drawButton( w, QPEDecoration::Help, helpState );
163 return true;
164 }
165 }
166 break;
167 case QEvent::MouseButtonRelease:
168 if ( helpState & QWSButton::Clicked ) {
169 helpState = 0;
170 drawButton( w, QPEDecoration::Help, helpState );
171 QPoint p = ((QMouseEvent*)e)->globalPos();
172 if ( pointInQpeRegion( w, p ) == QPEDecoration::Help ) {
173#ifdef WHATSTHIS_MODE
174 if ( pressTime.msecsTo( QTime::currentTime() ) > 250 ) {
175 decoration->help( w );
176 } else {
177 QWhatsThis::enterWhatsThisMode();
178 wtTimer->start( 200 );
179 }
180#else
181 decoration->help( w );
182#endif
183 }
184 return true;
185 }
186 break;
187 case QEvent::MouseMove:
188 if ( helpState & QWSButton::Clicked ) {
189 int oldState = helpState;
190 QPoint p = ((QMouseEvent*)e)->globalPos();
191 if ( pointInQpeRegion( w, p ) == QPEDecoration::Help )
192 helpState = QWSButton::Clicked|QWSButton::MouseOver;
193 else
194 helpState = 0;
195 if ( helpState != oldState )
196 drawButton( w, QPEDecoration::Help, helpState );
197 }
198 break;
199 default:
200 break;
201 }
202 return QObject::eventFilter( o, e );
203}
204
205void QPEManager::drawButton( QWidget *w, QPEDecoration::QPERegion r, int state )
206{
207 QPainter painter(w);
208 QRegion rgn = ((TLWidget *)w)->topExtra()->decor_allocated_region;
209 painter.internalGfx()->setWidgetDeviceRegion( rgn );
210 painter.setClipRegion(decoration->region(w, w->rect(),QWSDecoration::All));
211 decoration->paintButton( &painter, w, (QWSDecoration::Region)r, state );
212}
213
214void QPEManager::whatsThisTimeout()
215{
216 if ( !QWhatsThis::inWhatsThisMode() ) {
217 wtTimer->stop();
218 if ( active )
219 drawButton( active, QPEDecoration::Help, 0 );
220 } else if ( active ) {
221 static int state = 0;
222 if ( !state )
223 state = QWSButton::Clicked|QWSButton::MouseOver;
224 else
225 state = 0;
226 drawButton( active, QPEDecoration::Help, state );
227 }
228}
229
230//=========
231
232class HackWidget : public QWidget
233{
234public:
235 bool needsOk() { return (getWState() & WState_Reserved1 ); }
236};
237
238//===========================================================================
239
240QPEDecoration::QPEDecoration()
241 : QWSDefaultDecoration()
242{
243 imageOk = Resource::loadImage( "OKButton" );
244 imageClose = Resource::loadImage( "CloseButton" );
245 imageHelp = Resource::loadImage( "HelpButton" );
246 helpFile = QString(qApp->argv()[0]) + ".html";
247 QString lang = getenv( "LANG" );
248 helpExists = QFile::exists( QPEApplication::qpeDir() + "/help/" + lang + "/html/" + helpFile );
249 if ( !helpExists )
250 helpExists = QFile::exists( QPEApplication::qpeDir() + "/help/en/html/" + helpFile );
251#ifndef MINIMIZE_HELP_HACK
252 qpeManager = new QPEManager( this );
253#else
254 qpeManager = 0;
255#endif
256}
257
258QPEDecoration::~QPEDecoration()
259{
260 delete qpeManager;
261}
262
263const char **QPEDecoration::menuPixmap()
264{
265 return (const char **)0;
266}
267
268const char **QPEDecoration::closePixmap()
269{
270 return (const char **)qpe_close_xpm;
271}
272
273const char **QPEDecoration::minimizePixmap()
274{
275 return (const char **)qpe_accept_xpm;
276}
277
278const char **QPEDecoration::maximizePixmap()
279{
280 return (const char **)0;
281}
282
283const char **QPEDecoration::normalizePixmap()
284{
285 return (const char **)0;
286}
287
288int QPEDecoration::getTitleHeight(const QWidget *)
289{
290 return 15;
291}
292
293/*
294 If rect is empty, no frame is added. (a hack, really)
295*/
296QRegion QPEDecoration::region(const QWidget *widget, const QRect &rect, QWSDecoration::Region type)
297{
298 int titleHeight = getTitleHeight(widget);
299// int titleWidth = getTitleWidth(widget);
300// int bw = rect.isEmpty() ? 0 : BORDER_WIDTH;
301 QRegion region;
302
303#ifndef MINIMIZE_HELP_HACK
304 qpeManager->updateActive();
305#endif
306
307 switch ((int)type) {
308 case Menu:
309 case Maximize:
310 break;
311 case Minimize: {
312 if ( ((HackWidget *)widget)->needsOk() ||
313 (widget->inherits( "QDialog" ) && !widget->inherits( "QMessageBox" ) ) ) {
314 QRect r(rect.right() - imageOk.width(),
315 rect.top() - titleHeight - 2,
316 imageOk.width(), titleHeight);
317 if (r.left() > rect.left() + titleHeight)
318 region = r;
319 }
320#ifdef MINIMIZE_HELP_HACK
321 else if ( helpExists ) {
322 QRect r;
323 r = QRect(rect.right() - imageClose.width() - imageHelp.width(),
324 rect.top() - titleHeight - 2,
325 imageHelp.width(), titleHeight);
326 if (r.left() > rect.left() + titleHeight)
327 region = r;
328 }
329#endif
330 }
331 break;
332 case Close: {
333 if ( ((HackWidget *)widget)->needsOk() ||
334 (widget->inherits( "QDialog" ) && !widget->inherits( "QMessageBox" ) ) ) {
335 QRect r;
336 r = QRect(rect.right() - imageOk.width() - imageClose.width(),
337 rect.top() - titleHeight - 2,
338 imageClose.width(), titleHeight);
339 if (r.left() > rect.left() + titleHeight)
340 region = r;
341 } else {
342 QRect r(rect.right() - imageClose.width(),
343 rect.top() - titleHeight - 2,
344 imageClose.width(), titleHeight);
345 if (r.left() > rect.left() + titleHeight)
346 region = r;
347 }
348 break;
349 }
350 case Title: {
351 if ( widget->isMaximized() ) {
352 region = QRegion();
353 } else {
354 int btnWidth = imageClose.width();
355 if ( ((HackWidget *)widget)->needsOk() ||
356 (widget->inherits( "QDialog" ) && !widget->inherits( "QMessageBox" ) ) )
357 btnWidth += imageOk.width();
358 QRect r(rect.left() + 1, rect.top() - titleHeight,
359 rect.width() - btnWidth - 2, titleHeight);
360 if (r.width() > 0)
361 region = r;
362 }
363 break;
364 }
365 case Help: {
366 if ( helpExists ) {
367 QRect r;
368 int l = rect.right() - imageClose.width() - imageHelp.width();
369 if ( ((HackWidget *)widget)->needsOk() ||
370 (widget->inherits( "QDialog" ) && !widget->inherits( "QMessageBox" ) ) )
371 l -= imageOk.width();
372 r = QRect(l, rect.top() - titleHeight - 2,
373 imageHelp.width(), titleHeight);
374 if (r.left() > rect.left() + titleHeight)
375 region = r;
376 }
377 break;
378 }
379 case Top:
380 case Left:
381 case Right:
382 case Bottom:
383 case TopLeft:
384 case TopRight:
385 case BottomLeft:
386 case BottomRight:
387 if ( widget->isMaximized() ) {
388 region = QRegion();
389 break;
390 }
391 //else fallthrough!!!
392 case All:
393 default:
394 region = QWSDefaultDecoration::region(widget, rect, type);
395 break;
396 }
397
398 return region;
399}
400
401void QPEDecoration::paint(QPainter *painter, const QWidget *widget)
402{
403#ifndef QT_NO_STYLE
404// QStyle &style = QApplication::style();
405#endif
406
407 int titleWidth = getTitleWidth(widget);
408 int titleHeight = getTitleHeight(widget);
409
410 QRect rect(widget->rect());
411
412 // Border rect
413 QRect br( rect.left() - BORDER_WIDTH,
414 rect.top() - BORDER_WIDTH - titleHeight,
415 rect.width() + 2 * BORDER_WIDTH,
416 rect.height() + BORDER_WIDTH + BOTTOM_BORDER_WIDTH + titleHeight );
417
418 // title bar rect
419 QRect tr;
420
421 tr = QRect( rect.left(), rect.top() - titleHeight, rect.width(), titleHeight );
422
423 QRegion oldClip = painter->clipRegion();
424 painter->setClipRegion( oldClip - QRegion( tr ) );// reduce flicker
425
426#ifndef QT_NO_PALETTE
427 // const QColorGroup &cg = QApplication::palette().active();
428 const QColorGroup &cg = widget->palette().active();
429
430 qDrawWinPanel(painter, br.x(), br.y(), br.width(),
431 br.height() - 4, cg, FALSE,
432 &cg.brush(QColorGroup::Background));
433
434 painter->setClipRegion( oldClip );
435
436 if (titleWidth > 0) {
437 QBrush titleBrush;
438 QPen titlePen;
439 QPen titleLines;
440 int titleLeft = titleHeight + 4;
441
442 if (widget == qApp->activeWindow()) {
443 titleBrush = cg.brush(QColorGroup::Highlight);
444 titlePen = cg.color(QColorGroup::HighlightedText);
445 } else {
446 titleBrush = cg.brush(QColorGroup::Background);
447 titlePen = cg.color(QColorGroup::Text);
448 }
449
450 titleLines = titleBrush.color().dark(150);
451
452 #define CLAMP(x, y) ( ((x) > (y)) ? (y) : (x) )
453
454 titleLeft = rect.left() + 5;
455 painter->setPen( cg.midlight() );
456 painter->drawLine( rect.left() - BORDER_WIDTH + 2,
457 rect.bottom() + 1, rect.right() + BORDER_WIDTH - 2,
458 rect.bottom() + 1 );
459
460 fillTitle( painter, widget, rect.left() - 2,
461 rect.top() - titleHeight - 2,
462 rect.width() + 3, titleHeight + 2 );
463/*
464 painter->fillRect(rect.left() - 2,
465 rect.top() - titleHeight - 2,
466 rect.width() + 3, titleHeight + 2,
467 titleBrush);
468
469 painter->setPen( titleLines );
470 for ( int i = rect.top() - titleHeight - 2; i < rect.top(); i += 2 )
471 painter->drawLine( rect.left() - 2, i, rect.left() + rect.width() + 2, i );
472*/
473 painter->setPen(titlePen);
474 QFont f( QApplication::font() );
475 f.setWeight( QFont::Bold );
476 painter->setFont(f);
477 painter->drawText( titleLeft, -titleHeight,
478 rect.width() - titleHeight - 10, titleHeight-1,
479 QPainter::AlignVCenter, widget->caption());
480 }
481
482#endif //QT_NO_PALETTE
483
484#ifndef MINIMIZE_HELP_HACK
485 paintButton( painter, widget, (QWSDecoration::Region)Help, 0 );
486#endif
487}
488
489void QPEDecoration::paintButton(QPainter *painter, const QWidget *w,
490 QWSDecoration::Region type, int state)
491{
492#ifndef QT_NO_PALETTE
493#ifndef QT_NO_STYLE
494// QStyle &style = QApplication::style();
495#endif
496 const QColorGroup &cg = w->palette().active();
497
498 QRect brect(region(w, w->rect(), type).boundingRect());
499
500// int xoff=2;
501// int yoff=2;
502
503// const QPixmap *pm=pixmapFor(w,type,state & QWSButton::On, xoff, yoff);
504
505 const QImage *img = 0;
506
507 switch ((int)type) {
508 case Close:
509 img = &imageClose;
510 break;
511 case Minimize:
512 if ( ((HackWidget *)w)->needsOk() ||
513 (w->inherits( "QDialog" ) && !w->inherits( "QMessageBox" ) ) )
514 img = &imageOk;
515 else if ( helpExists )
516 img = &imageHelp;
517 break;
518 case Help:
519 img = &imageHelp;
520 break;
521 default:
522 return;
523 }
524
525 QBrush titleBrush;
526
527 if (w == qApp->activeWindow()) {
528 titleBrush = cg.brush(QColorGroup::Highlight);
529 } else {
530 titleBrush = cg.brush(QColorGroup::Background);
531 }
532
533 fillTitle( painter, w, brect.x(), brect.y(), brect.width()+1,
534 brect.height()+1 );
535 if ((state & QWSButton::MouseOver) && (state & QWSButton::Clicked)) {
536 if (img) painter->drawImage(brect.x()+1, brect.y()+3, *img);
537 } else {
538 if (img) painter->drawImage(brect.x(), brect.y()+2, *img);
539 }
540
541#endif
542
543}
544
545void QPEDecoration::fillTitle( QPainter *p, const QWidget *widget,
546 int x, int y, int w, int h )
547{
548 QBrush titleBrush;
549 QPen topLine;
550 QPen titleLines;
551
552 const QColorGroup &cg = widget->palette().active();
553
554 if (widget == qApp->activeWindow()) {
555 titleBrush = cg.brush(QColorGroup::Highlight);
556 titleLines = titleBrush.color().dark();
557 topLine = titleBrush.color().light();
558 } else {
559 titleBrush = cg.brush(QColorGroup::Background);
560 titleLines = titleBrush.color();
561 topLine = titleBrush.color();
562 }
563
564 p->fillRect( x, y, w, h, titleBrush);
565
566 p->setPen( topLine );
567 p->drawLine( x, y+1, x+w-1, y+1 );
568 p->setPen( titleLines );
569 for ( int i = y; i < y+h; i += 2 )
570 p->drawLine( x, i, x+w-1, i );
571}
572
573//#define QPE_DONT_SHOW_TITLEBAR
574
575void QPEDecoration::maximize( QWidget *widget )
576{
577#ifdef QPE_DONT_SHOW_TITLEBAR
578 if ( !widget->inherits( "QDialog" ) ) {
579 widget->setGeometry( qt_maxWindowRect );
580 } else
581 #endif
582 {
583 QWSDecoration::maximize( widget );
584 }
585}
586
587#ifndef QT_NO_DIALOG
588class HackDialog : public QDialog
589{
590public:
591 void acceptIt() {
592 if ( isA( "QMessageBox" ) )
593 qApp->postEvent( this, new QKeyEvent( QEvent::KeyPress, Key_Enter, '\n', 0, "\n" ) );
594 else
595 accept();
596 }
597};
598#endif
599
600
601void QPEDecoration::minimize( QWidget *widget )
602{
603#ifndef QT_NO_DIALOG
604 // We use the minimize button as an "accept" button.
605 if ( widget->inherits( "QDialog" ) ) {
606 HackDialog *d = (HackDialog *)widget;
607 d->acceptIt();
608 }
609#endif
610 else if ( ((HackWidget *)widget)->needsOk() ) {
611 QSignal s;
612 s.connect( widget, SLOT( accept() ) );
613 s.activate();
614 } else {
615 help( widget );
616 }
617}
618
619void QPEDecoration::help( QWidget * )
620{
621 if ( helpExists ) {
622 Global::execute( "helpbrowser", helpFile );
623 }
624}
625
626
627/*
628#ifndef QT_NO_POPUPMENU
629QPopupMenu *QPEDecoration::menu(QWSManager*, const QWidget*, const QPoint&)
630{
631 return 0;
632}
633#endif
634*/
635
636
637
638
639#endif // QT_NO_QWS_QPE_WM_STYLE