mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 19:02:51 +00:00
223 lines
5.8 KiB
C++
223 lines
5.8 KiB
C++
![]() |
/*
|
||
|
Copyright (C) 2006 Oswald Buddenhagen <ossi@kde.org>
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "positioner.h"
|
||
|
|
||
|
#include <klocale.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
|
||
|
#include <QFrame>
|
||
|
#include <QLabel>
|
||
|
#include <QMouseEvent>
|
||
|
#include <QDesktopWidget>
|
||
|
#include <QApplication>
|
||
|
|
||
|
#define TOTAL_WIDTH 200
|
||
|
#define TOTAL_HEIGHT 186
|
||
|
#define ACTIVE_X 23
|
||
|
#define ACTIVE_Y 14
|
||
|
#define ACTIVE_WIDTH 151
|
||
|
#define ACTIVE_HEIGHT 115
|
||
|
#define MARGIN 10
|
||
|
|
||
|
#define SNAP 10
|
||
|
#define STEP 5
|
||
|
|
||
|
static void
|
||
|
fit(int &p)
|
||
|
{
|
||
|
if (p < SNAP)
|
||
|
p = 0;
|
||
|
else if (p > 100 - SNAP)
|
||
|
p = 100;
|
||
|
else if (p > 50 - SNAP / 2 && p < 50 + SNAP / 2)
|
||
|
p = 50;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
step(int &p, int d)
|
||
|
{
|
||
|
if (p < SNAP)
|
||
|
p = 0 + (d + 1) * SNAP / 2;
|
||
|
else if (p > 100 - SNAP)
|
||
|
p = 100 + (d - 1) * SNAP / 2;
|
||
|
else if (p > 50 - SNAP / 2 && p < 50 + SNAP / 2)
|
||
|
p = 50 + d * SNAP / 2;
|
||
|
else {
|
||
|
p += d * STEP;
|
||
|
fit(p);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Positioner::Positioner(QWidget *parent)
|
||
|
: ScreenPreviewWidget(parent)
|
||
|
, m_x(50)
|
||
|
, m_y(50)
|
||
|
{
|
||
|
QDesktopWidget *desktop = QApplication::desktop();
|
||
|
setRatio((qreal)desktop->width() / (qreal)desktop->height());
|
||
|
m_anchor = QPixmap(KStandardDirs::locate("data", "kcontrol/pics/anchor.png"));
|
||
|
setFocusPolicy(Qt::StrongFocus);
|
||
|
const int fw = MARGIN * 2;
|
||
|
setMinimumSize(TOTAL_WIDTH + fw, TOTAL_HEIGHT + fw);
|
||
|
setMaximumWidth(400);
|
||
|
QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||
|
sp.setHeightForWidth(true);
|
||
|
setSizePolicy(sp);
|
||
|
m_frame = new QFrame(this);
|
||
|
m_screen = new QWidget(m_frame);
|
||
|
m_screen->setAutoFillBackground(true);
|
||
|
QPalette pal;
|
||
|
pal.setColor(QPalette::Background, QColor(255, 255, 255, 128));
|
||
|
m_screen->setPalette(pal);
|
||
|
m_dlg = new QFrame(m_screen);
|
||
|
m_dlg->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||
|
m_dlg->setAutoFillBackground(true);
|
||
|
QPalette pal2;
|
||
|
pal2.setBrush(QPalette::Background, pal2.brush(QPalette::Normal, QPalette::Background));
|
||
|
m_dlg->setPalette(pal2);
|
||
|
m_ptr = new QLabel(m_screen);
|
||
|
m_ptr->setPixmap(m_anchor);
|
||
|
QString wts(i18n(
|
||
|
"Drag the anchor to move the center of the dialog to the desired position. "
|
||
|
"Keyboard control is possible as well: Use the arrow keys or Home to center. "
|
||
|
"Note that the actual proportions of the dialog are probably different."));
|
||
|
m_frame->setWhatsThis(wts);
|
||
|
m_screen->setWhatsThis(wts);
|
||
|
m_ptr->setWhatsThis(wts);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::setPosition(int x, int y)
|
||
|
{
|
||
|
m_x = x;
|
||
|
m_y = y;
|
||
|
updateHandle();
|
||
|
}
|
||
|
|
||
|
int
|
||
|
Positioner::heightForWidth(int w) const
|
||
|
{
|
||
|
const int fw = MARGIN * 2;
|
||
|
return ((w - fw) * TOTAL_HEIGHT + (TOTAL_WIDTH / 2)) / TOTAL_WIDTH + fw;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::updateHandle()
|
||
|
{
|
||
|
int px = m_screen->size().width() * m_x / 100;
|
||
|
int py = m_screen->size().height() * m_y / 100;
|
||
|
m_ptr->setGeometry(px - m_anchor.width() / 2, py - m_anchor.height() / 2,
|
||
|
m_anchor.width(), m_anchor.height());
|
||
|
int sw = m_screen->width() * 2 / 5;
|
||
|
int sh = m_screen->height() * 2 / 5;
|
||
|
QRect grt(px - sw / 2, py - sh / 2, sw, sh);
|
||
|
int di;
|
||
|
if ((di = m_screen->size().width() - grt.right()) < 0)
|
||
|
grt.translate(di, 0);
|
||
|
if ((di = - grt.left()) > 0)
|
||
|
grt.translate(di, 0);
|
||
|
if ((di = m_screen->size().height() - grt.bottom()) < 0)
|
||
|
grt.translate(0, di);
|
||
|
if ((di = - grt.top()) > 0)
|
||
|
grt.translate(0, di);
|
||
|
m_dlg->setGeometry(grt);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::resizeEvent(QResizeEvent *event)
|
||
|
{
|
||
|
ScreenPreviewWidget::resizeEvent(event);
|
||
|
const int fw = MARGIN * 2;
|
||
|
QSize rs(TOTAL_WIDTH, TOTAL_HEIGHT);
|
||
|
rs.scale(size() - QSize(fw, fw), Qt::KeepAspectRatio);
|
||
|
|
||
|
m_frame->setGeometry(0, 0, rs.width() + fw, rs.height() + fw);
|
||
|
m_frame->resize(size());
|
||
|
m_screen->setGeometry(previewRect());
|
||
|
|
||
|
updateHandle();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::focusInEvent(QFocusEvent *)
|
||
|
{
|
||
|
m_frame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::focusOutEvent(QFocusEvent *)
|
||
|
{
|
||
|
m_frame->setFrameStyle(QFrame::NoFrame);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::mousePressEvent(QMouseEvent *event)
|
||
|
{
|
||
|
QPoint cp = event->pos() - m_screen->pos();
|
||
|
if (m_ptr->geometry().contains(cp))
|
||
|
m_delta = m_ptr->geometry().center() - cp;
|
||
|
else
|
||
|
m_delta.setX(-1);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::mouseMoveEvent(QMouseEvent *event)
|
||
|
{
|
||
|
if (m_delta.x() != -1) {
|
||
|
QPoint cp = event->pos() - m_screen->pos() + m_delta;
|
||
|
m_x = cp.x() * 100 / m_screen->size().width();
|
||
|
m_y = cp.y() * 100 / m_screen->size().height();
|
||
|
fit(m_x);
|
||
|
fit(m_y);
|
||
|
updateHandle();
|
||
|
emit positionChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Positioner::keyPressEvent(QKeyEvent *event)
|
||
|
{
|
||
|
switch (event->key()) {
|
||
|
case Qt::Key_Home:
|
||
|
m_x = m_y = 50;
|
||
|
break;
|
||
|
case Qt::Key_Left:
|
||
|
step(m_x, -1);
|
||
|
break;
|
||
|
case Qt::Key_Right:
|
||
|
step(m_x, 1);
|
||
|
break;
|
||
|
case Qt::Key_Up:
|
||
|
step(m_y, -1);
|
||
|
break;
|
||
|
case Qt::Key_Down:
|
||
|
step(m_y, 1);
|
||
|
break;
|
||
|
default:
|
||
|
event->ignore();
|
||
|
return;
|
||
|
}
|
||
|
updateHandle();
|
||
|
emit positionChanged();
|
||
|
event->accept();
|
||
|
}
|
||
|
|
||
|
#include "positioner.moc"
|