1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
6 Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *********************************************************************/
22 #include "mousemark.h"
24 #include <kwinconfig.h>
27 #include <kactioncollection.h>
30 #include <kstandarddirs.h>
31 #include <kconfiggroup.h>
35 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
44 #define NULL_POINT (QPoint( -1, -1 )) // null point is (0,0), which is valid :-/
46 KWIN_EFFECT( mousemark
, MouseMarkEffect
)
48 MouseMarkEffect::MouseMarkEffect()
50 KActionCollection
* actionCollection
= new KActionCollection( this );
51 KAction
* a
= static_cast< KAction
* >( actionCollection
->addAction( "ClearMouseMarks" ));
52 a
->setText( i18n( "Clear All Mouse Marks" ));
53 a
->setGlobalShortcut( KShortcut( Qt::SHIFT
+ Qt::META
+ Qt::Key_F11
));
54 connect( a
, SIGNAL( triggered( bool )), this, SLOT( clear()));
55 a
= static_cast< KAction
* >( actionCollection
->addAction( "ClearLastMouseMark" ));
56 a
->setText( i18n( "Clear Last Mouse Mark" ));
57 a
->setGlobalShortcut( KShortcut( Qt::SHIFT
+ Qt::META
+ Qt::Key_F12
));
58 connect( a
, SIGNAL( triggered( bool )), this, SLOT( clearLast()));
60 KConfigGroup conf
= EffectsHandler::effectConfig("MouseMark");
61 width
= conf
.readEntry( "LineWidth", 3 );
62 color
= conf
.readEntry( "Color", QColor( Qt::red
));
64 arrow_start
= NULL_POINT
;
67 void MouseMarkEffect::paintScreen( int mask
, QRegion region
, ScreenPaintData
& data
)
69 effects
->paintScreen( mask
, region
, data
); // paint normal screen
70 if( marks
.isEmpty() && drawing
.isEmpty())
72 glPushAttrib( GL_ENABLE_BIT
| GL_CURRENT_BIT
| GL_LINE_BIT
);
73 glColor4f( color
.redF(), color
.greenF(), color
.blueF(), 1 );
74 glEnable( GL_LINE_SMOOTH
);
76 foreach( const Mark
& mark
, marks
)
78 glBegin( GL_LINE_STRIP
);
79 foreach( const QPoint
& p
, mark
)
80 glVertex2i( p
.x(), p
.y());
83 if( !drawing
.isEmpty())
85 glBegin( GL_LINE_STRIP
);
86 foreach( const QPoint
& p
, drawing
)
87 glVertex2i( p
.x(), p
.y());
93 void MouseMarkEffect::mouseChanged( const QPoint
& pos
, const QPoint
&,
94 Qt::MouseButtons
, Qt::MouseButtons
,
95 Qt::KeyboardModifiers modifiers
, Qt::KeyboardModifiers
)
97 if( modifiers
== ( Qt::META
| Qt::SHIFT
| Qt::CTRL
)) // start/finish arrow
99 if( arrow_start
!= NULL_POINT
)
101 marks
.append( createArrow( arrow_start
, pos
));
102 arrow_start
= NULL_POINT
;
103 effects
->addRepaintFull();
109 if( arrow_start
!= NULL_POINT
)
111 // TODO the shortcuts now trigger this right before they're activated
112 if( modifiers
== ( Qt::META
| Qt::SHIFT
)) // activated
114 if( drawing
.isEmpty())
115 drawing
.append( pos
);
116 if( drawing
.last() == pos
)
118 QPoint pos2
= drawing
.last();
119 drawing
.append( pos
);
120 QRect repaint
= QRect( qMin( pos
.x(), pos2
.x()), qMin( pos
.y(), pos2
.y()),
121 qMax( pos
.x(), pos2
.x()), qMax( pos
.y(), pos2
.y()));
122 repaint
.adjust( -width
, -width
, width
, width
);
123 effects
->addRepaint( repaint
);
125 else if( !drawing
.isEmpty())
127 marks
.append( drawing
);
132 void MouseMarkEffect::clear()
136 effects
->addRepaintFull();
139 void MouseMarkEffect::clearLast()
141 if( arrow_start
!= NULL_POINT
)
143 arrow_start
= NULL_POINT
;
145 else if( !drawing
.isEmpty())
148 effects
->addRepaintFull();
150 else if( !marks
.isEmpty())
153 effects
->addRepaintFull();
157 MouseMarkEffect::Mark
MouseMarkEffect::createArrow( QPoint arrow_start
, QPoint arrow_end
)
160 double angle
= atan2( (double) (arrow_end
.y() - arrow_start
.y()), (double) (arrow_end
.x() - arrow_start
.x()));
161 ret
+= arrow_start
+ QPoint( 50 * cos( angle
+ M_PI
/ 6 ),
162 50 * sin( angle
+ M_PI
/ 6 )); // right one
165 ret
+= arrow_start
; // it's connected lines, so go back with the middle one
166 ret
+= arrow_start
+ QPoint( 50 * cos( angle
- M_PI
/ 6 ),
167 50 * sin( angle
- M_PI
/ 6 )); // left one
173 #include "mousemark.moc"