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()));
59 reconfigure( ReconfigureAll
);
60 arrow_start
= NULL_POINT
;
63 void MouseMarkEffect::reconfigure( ReconfigureFlags
)
65 KConfigGroup conf
= EffectsHandler::effectConfig("MouseMark");
66 width
= conf
.readEntry( "LineWidth", 3 );
67 color
= conf
.readEntry( "Color", QColor( Qt::red
));
70 void MouseMarkEffect::paintScreen( int mask
, QRegion region
, ScreenPaintData
& data
)
72 effects
->paintScreen( mask
, region
, data
); // paint normal screen
73 if( marks
.isEmpty() && drawing
.isEmpty())
75 glPushAttrib( GL_ENABLE_BIT
| GL_CURRENT_BIT
| GL_LINE_BIT
);
76 glColor4f( color
.redF(), color
.greenF(), color
.blueF(), 1 );
77 glEnable( GL_LINE_SMOOTH
);
79 foreach( const Mark
& mark
, marks
)
81 glBegin( GL_LINE_STRIP
);
82 foreach( const QPoint
& p
, mark
)
83 glVertex2i( p
.x(), p
.y());
86 if( !drawing
.isEmpty())
88 glBegin( GL_LINE_STRIP
);
89 foreach( const QPoint
& p
, drawing
)
90 glVertex2i( p
.x(), p
.y());
96 void MouseMarkEffect::mouseChanged( const QPoint
& pos
, const QPoint
&,
97 Qt::MouseButtons
, Qt::MouseButtons
,
98 Qt::KeyboardModifiers modifiers
, Qt::KeyboardModifiers
)
100 if( modifiers
== ( Qt::META
| Qt::SHIFT
| Qt::CTRL
)) // start/finish arrow
102 if( arrow_start
!= NULL_POINT
)
104 marks
.append( createArrow( arrow_start
, pos
));
105 arrow_start
= NULL_POINT
;
106 effects
->addRepaintFull();
112 if( arrow_start
!= NULL_POINT
)
114 // TODO the shortcuts now trigger this right before they're activated
115 if( modifiers
== ( Qt::META
| Qt::SHIFT
)) // activated
117 if( drawing
.isEmpty())
118 drawing
.append( pos
);
119 if( drawing
.last() == pos
)
121 QPoint pos2
= drawing
.last();
122 drawing
.append( pos
);
123 QRect repaint
= QRect( qMin( pos
.x(), pos2
.x()), qMin( pos
.y(), pos2
.y()),
124 qMax( pos
.x(), pos2
.x()), qMax( pos
.y(), pos2
.y()));
125 repaint
.adjust( -width
, -width
, width
, width
);
126 effects
->addRepaint( repaint
);
128 else if( !drawing
.isEmpty())
130 marks
.append( drawing
);
135 void MouseMarkEffect::clear()
139 effects
->addRepaintFull();
142 void MouseMarkEffect::clearLast()
144 if( arrow_start
!= NULL_POINT
)
146 arrow_start
= NULL_POINT
;
148 else if( !drawing
.isEmpty())
151 effects
->addRepaintFull();
153 else if( !marks
.isEmpty())
156 effects
->addRepaintFull();
160 MouseMarkEffect::Mark
MouseMarkEffect::createArrow( QPoint arrow_start
, QPoint arrow_end
)
163 double angle
= atan2( (double) (arrow_end
.y() - arrow_start
.y()), (double) (arrow_end
.x() - arrow_start
.x()));
164 ret
+= arrow_start
+ QPoint( 50 * cos( angle
+ M_PI
/ 6 ),
165 50 * sin( angle
+ M_PI
/ 6 )); // right one
168 ret
+= arrow_start
; // it's connected lines, so go back with the middle one
169 ret
+= arrow_start
+ QPoint( 50 * cos( angle
- M_PI
/ 6 ),
170 50 * sin( angle
- M_PI
/ 6 )); // left one
176 #include "mousemark.moc"