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

« back to all changes in this revision

Viewing changes to kwin/effects/magnifier/magnifier.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) 2007 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 "magnifier.h"
 
23
 
 
24
#include <kwinconfig.h>
 
25
 
 
26
#include <kaction.h>
 
27
#include <kactioncollection.h>
 
28
#include <kconfiggroup.h>
 
29
#include <kstandardaction.h>
 
30
 
 
31
#include <kwinglutils.h>
 
32
 
 
33
namespace KWin
 
34
{
 
35
 
 
36
KWIN_EFFECT(magnifier, MagnifierEffect)
 
37
 
 
38
const int FRAME_WIDTH = 5;
 
39
 
 
40
MagnifierEffect::MagnifierEffect()
 
41
    : zoom(1)
 
42
    , target_zoom(1)
 
43
    , polling(false)
 
44
{
 
45
    KActionCollection* actionCollection = new KActionCollection(this);
 
46
    KAction* a;
 
47
    a = static_cast< KAction* >(actionCollection->addAction(KStandardAction::ZoomIn, this, SLOT(zoomIn())));
 
48
    a->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Equal));
 
49
    a = static_cast< KAction* >(actionCollection->addAction(KStandardAction::ZoomOut, this, SLOT(zoomOut())));
 
50
    a->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Minus));
 
51
    a = static_cast< KAction* >(actionCollection->addAction(KStandardAction::ActualSize, this, SLOT(toggle())));
 
52
    a->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_0));
 
53
    connect(effects, SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)),
 
54
            this, SLOT(slotMouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)));
 
55
    reconfigure(ReconfigureAll);
 
56
}
 
57
 
 
58
void MagnifierEffect::reconfigure(ReconfigureFlags)
 
59
{
 
60
    KConfigGroup conf = EffectsHandler::effectConfig("Magnifier");
 
61
    int width, height;
 
62
    width = conf.readEntry("Width", 200);
 
63
    height = conf.readEntry("Height", 200);
 
64
    magnifier_size = QSize(width, height);
 
65
}
 
66
 
 
67
void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
68
{
 
69
    if (zoom != target_zoom) {
 
70
        double diff = time / animationTime(500.0);
 
71
        if (target_zoom > zoom)
 
72
            zoom = qMin(zoom * qMax(1 + diff, 1.2), target_zoom);
 
73
        else
 
74
            zoom = qMax(zoom * qMin(1 - diff, 0.8), target_zoom);
 
75
    }
 
76
    effects->prePaintScreen(data, time);
 
77
    if (zoom != 1.0)
 
78
        data.paint |= magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
 
79
}
 
80
 
 
81
void MagnifierEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
 
82
{
 
83
    ScreenPaintData data2 = data;
 
84
    effects->paintScreen(mask, region, data);   // paint normal screen
 
85
    if (zoom != 1.0) {
 
86
        // paint magnifier
 
87
        QRect area = magnifierArea();
 
88
        PaintClipper::push(area);   // don't allow any painting outside of the area
 
89
        mask |= PAINT_SCREEN_TRANSFORMED;
 
90
        data2.xScale *= zoom;
 
91
        data2.yScale *= zoom;
 
92
        QPoint cursor = cursorPos();
 
93
        // set the position so that the cursor is in the same position in the scaled view
 
94
        data2.xTranslate = - int(cursor.x() * (zoom - 1));
 
95
        data2.yTranslate = - int(cursor.y() * (zoom - 1));
 
96
        effects->paintScreen(mask, region, data2);
 
97
        PaintClipper::pop(area);
 
98
        QVector<float> verts;
 
99
        GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
 
100
        vbo->reset();
 
101
        vbo->setColor(QColor(0, 0, 0));
 
102
        // top frame
 
103
        verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
104
        verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
105
        verts << area.left() - FRAME_WIDTH << area.top() - 1;
 
106
        verts << area.left() - FRAME_WIDTH << area.top() - 1;
 
107
        verts << area.right() + FRAME_WIDTH << area.top() - 1;
 
108
        verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
109
        // left frame
 
110
        verts << area.left() - 1 << area.top() - FRAME_WIDTH;
 
111
        verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
112
        verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
113
        verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
114
        verts << area.left() - 1 << area.bottom() + FRAME_WIDTH;
 
115
        verts << area.left() - 1 << area.top() - FRAME_WIDTH;
 
116
        // right frame
 
117
        verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
118
        verts << area.right() + 1 << area.top() - FRAME_WIDTH;
 
119
        verts << area.right() + 1 << area.bottom() + FRAME_WIDTH;
 
120
        verts << area.right() + 1 << area.bottom() + FRAME_WIDTH;
 
121
        verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
122
        verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH;
 
123
        // bottom frame
 
124
        verts << area.right() + FRAME_WIDTH << area.bottom() + 1;
 
125
        verts << area.left() - FRAME_WIDTH << area.bottom() + 1;
 
126
        verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
127
        verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
128
        verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH;
 
129
        verts << area.right() + FRAME_WIDTH << area.bottom() + 1;
 
130
        vbo->setData(verts.size() / 2, 2, verts.constData(), NULL);
 
131
        if (ShaderManager::instance()->isValid()) {
 
132
            ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
 
133
        }
 
134
        vbo->render(GL_TRIANGLES);
 
135
        if (ShaderManager::instance()->isValid()) {
 
136
            ShaderManager::instance()->popShader();
 
137
        }
 
138
    }
 
139
}
 
140
 
 
141
void MagnifierEffect::postPaintScreen()
 
142
{
 
143
    if (zoom != target_zoom) {
 
144
        QRect framedarea = magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
 
145
        effects->addRepaint(framedarea);
 
146
    }
 
147
    effects->postPaintScreen();
 
148
}
 
149
 
 
150
QRect MagnifierEffect::magnifierArea(QPoint pos) const
 
151
{
 
152
    return QRect(pos.x() - magnifier_size.width() / 2, pos.y() - magnifier_size.height() / 2,
 
153
                 magnifier_size.width(), magnifier_size.height());
 
154
}
 
155
 
 
156
void MagnifierEffect::zoomIn()
 
157
{
 
158
    target_zoom *= 1.2;
 
159
    if (!polling) {
 
160
        polling = true;
 
161
        effects->startMousePolling();
 
162
    }
 
163
    effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
 
164
}
 
165
 
 
166
void MagnifierEffect::zoomOut()
 
167
{
 
168
    target_zoom /= 1.2;
 
169
    if (target_zoom < 1) {
 
170
        target_zoom = 1;
 
171
        if (polling) {
 
172
            polling = false;
 
173
            effects->stopMousePolling();
 
174
        }
 
175
    }
 
176
    effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
 
177
}
 
178
 
 
179
void MagnifierEffect::toggle()
 
180
{
 
181
    if (target_zoom == 1.0) {
 
182
        target_zoom = 2;
 
183
        if (!polling) {
 
184
            polling = true;
 
185
            effects->startMousePolling();
 
186
        }
 
187
    } else {
 
188
        target_zoom = 1;
 
189
        if (polling) {
 
190
            polling = false;
 
191
            effects->stopMousePolling();
 
192
        }
 
193
    }
 
194
    effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
 
195
}
 
196
 
 
197
void MagnifierEffect::slotMouseChanged(const QPoint& pos, const QPoint& old,
 
198
                                   Qt::MouseButtons, Qt::MouseButtons, Qt::KeyboardModifiers, Qt::KeyboardModifiers)
 
199
{
 
200
    if (pos != old && zoom != 1)
 
201
        // need full repaint as we might lose some change events on fast mouse movements
 
202
        // see Bug 187658
 
203
        effects->addRepaintFull();
 
204
}
 
205
 
 
206
} // namespace
 
207
 
 
208
#include "magnifier.moc"