~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kwin/effects/mousemark/mousemark.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 KWin - the KDE window manager
 
3
 This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
 
6
Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
 
7
 
 
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.
 
12
 
 
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.
 
17
 
 
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
*********************************************************************/
 
21
 
 
22
#include "mousemark.h"
 
23
 
 
24
#include <kwinconfig.h>
 
25
#include <kwinglutils.h>
 
26
 
 
27
#include <kaction.h>
 
28
#include <kactioncollection.h>
 
29
#include <kglobal.h>
 
30
#include <klocale.h>
 
31
#include <kstandarddirs.h>
 
32
#include <kconfiggroup.h>
 
33
 
 
34
#include <math.h>
 
35
 
 
36
#include <kdebug.h>
 
37
 
 
38
namespace KWin
 
39
{
 
40
 
 
41
#define NULL_POINT (QPoint( -1, -1 )) // null point is (0,0), which is valid :-/
 
42
 
 
43
KWIN_EFFECT(mousemark, MouseMarkEffect)
 
44
 
 
45
MouseMarkEffect::MouseMarkEffect()
 
46
{
 
47
    KActionCollection* actionCollection = new KActionCollection(this);
 
48
    KAction* a = static_cast< KAction* >(actionCollection->addAction("ClearMouseMarks"));
 
49
    a->setText(i18n("Clear All Mouse Marks"));
 
50
    a->setGlobalShortcut(KShortcut(Qt::SHIFT + Qt::META + Qt::Key_F11));
 
51
    connect(a, SIGNAL(triggered(bool)), this, SLOT(clear()));
 
52
    a = static_cast< KAction* >(actionCollection->addAction("ClearLastMouseMark"));
 
53
    a->setText(i18n("Clear Last Mouse Mark"));
 
54
    a->setGlobalShortcut(KShortcut(Qt::SHIFT + Qt::META + Qt::Key_F12));
 
55
    connect(a, SIGNAL(triggered(bool)), this, SLOT(clearLast()));
 
56
    connect(effects, SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)),
 
57
            this, SLOT(slotMouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)));
 
58
    reconfigure(ReconfigureAll);
 
59
    arrow_start = NULL_POINT;
 
60
    effects->startMousePolling(); // We require it to detect activation as well
 
61
}
 
62
 
 
63
MouseMarkEffect::~MouseMarkEffect()
 
64
{
 
65
    effects->stopMousePolling();
 
66
}
 
67
 
 
68
void MouseMarkEffect::reconfigure(ReconfigureFlags)
 
69
{
 
70
    KConfigGroup conf = EffectsHandler::effectConfig("MouseMark");
 
71
    width = conf.readEntry("LineWidth", 3);
 
72
    color = conf.readEntry("Color", QColor(Qt::red));
 
73
    color.setAlphaF(1.0);
 
74
}
 
75
 
 
76
void MouseMarkEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
 
77
{
 
78
    effects->paintScreen(mask, region, data);   // paint normal screen
 
79
    if (marks.isEmpty() && drawing.isEmpty())
 
80
        return;
 
81
#ifndef KWIN_HAVE_OPENGLES
 
82
    glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT);
 
83
    glEnable(GL_LINE_SMOOTH);
 
84
#endif
 
85
    glLineWidth(width);
 
86
    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
 
87
    vbo->reset();
 
88
    vbo->setUseColor(true);
 
89
    vbo->setColor(color);
 
90
    if (ShaderManager::instance()->isValid()) {
 
91
        ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
 
92
    }
 
93
    QVector<float> verts;
 
94
    foreach (const Mark & mark, marks) {
 
95
        verts.clear();
 
96
        verts.reserve(mark.size() * 2);
 
97
        foreach (const QPoint & p, mark) {
 
98
            verts << p.x() << p.y();
 
99
        }
 
100
        vbo->setData(verts.size() / 2, 2, verts.data(), NULL);
 
101
        vbo->render(GL_LINE_STRIP);
 
102
    }
 
103
    if (!drawing.isEmpty()) {
 
104
        verts.clear();
 
105
        verts.reserve(drawing.size() * 2);
 
106
        foreach (const QPoint & p, drawing) {
 
107
            verts << p.x() << p.y();
 
108
        }
 
109
        vbo->setData(verts.size() / 2, 2, verts.data(), NULL);
 
110
        vbo->render(GL_LINE_STRIP);
 
111
    }
 
112
    if (ShaderManager::instance()->isValid()) {
 
113
        ShaderManager::instance()->popShader();
 
114
    }
 
115
    glLineWidth(1.0);
 
116
#ifndef KWIN_HAVE_OPENGLES
 
117
    glDisable(GL_LINE_SMOOTH);
 
118
    glPopAttrib();
 
119
#endif
 
120
}
 
121
 
 
122
void MouseMarkEffect::slotMouseChanged(const QPoint& pos, const QPoint&,
 
123
                                   Qt::MouseButtons, Qt::MouseButtons,
 
124
                                   Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers)
 
125
{
 
126
    if (modifiers == (Qt::META | Qt::SHIFT | Qt::CTRL)) {  // start/finish arrow
 
127
        if (arrow_start != NULL_POINT) {
 
128
            marks.append(createArrow(arrow_start, pos));
 
129
            arrow_start = NULL_POINT;
 
130
            effects->addRepaintFull();
 
131
            return;
 
132
        } else
 
133
            arrow_start = pos;
 
134
    }
 
135
    if (arrow_start != NULL_POINT)
 
136
        return;
 
137
    // TODO the shortcuts now trigger this right before they're activated
 
138
    if (modifiers == (Qt::META | Qt::SHIFT)) {  // activated
 
139
        if (drawing.isEmpty())
 
140
            drawing.append(pos);
 
141
        if (drawing.last() == pos)
 
142
            return;
 
143
        QPoint pos2 = drawing.last();
 
144
        drawing.append(pos);
 
145
        QRect repaint = QRect(qMin(pos.x(), pos2.x()), qMin(pos.y(), pos2.y()),
 
146
                              qMax(pos.x(), pos2.x()), qMax(pos.y(), pos2.y()));
 
147
        repaint.adjust(-width, -width, width, width);
 
148
        effects->addRepaint(repaint);
 
149
    } else if (!drawing.isEmpty()) {
 
150
        marks.append(drawing);
 
151
        drawing.clear();
 
152
    }
 
153
}
 
154
 
 
155
void MouseMarkEffect::clear()
 
156
{
 
157
    drawing.clear();
 
158
    marks.clear();
 
159
    effects->addRepaintFull();
 
160
}
 
161
 
 
162
void MouseMarkEffect::clearLast()
 
163
{
 
164
    if (arrow_start != NULL_POINT) {
 
165
        arrow_start = NULL_POINT;
 
166
    } else if (!drawing.isEmpty()) {
 
167
        drawing.clear();
 
168
        effects->addRepaintFull();
 
169
    } else if (!marks.isEmpty()) {
 
170
        marks.pop_back();
 
171
        effects->addRepaintFull();
 
172
    }
 
173
}
 
174
 
 
175
MouseMarkEffect::Mark MouseMarkEffect::createArrow(QPoint arrow_start, QPoint arrow_end)
 
176
{
 
177
    Mark ret;
 
178
    double angle = atan2((double)(arrow_end.y() - arrow_start.y()), (double)(arrow_end.x() - arrow_start.x()));
 
179
    ret += arrow_start + QPoint(50 * cos(angle + M_PI / 6),
 
180
                                50 * sin(angle + M_PI / 6));   // right one
 
181
    ret += arrow_start;
 
182
    ret += arrow_end;
 
183
    ret += arrow_start; // it's connected lines, so go back with the middle one
 
184
    ret += arrow_start + QPoint(50 * cos(angle - M_PI / 6),
 
185
                                50 * sin(angle - M_PI / 6));   // left one
 
186
    return ret;
 
187
}
 
188
 
 
189
} // namespace
 
190
 
 
191
#include "mousemark.moc"