kexi

resizehandle.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
00003    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <kdebug.h>
00021 #include <klocale.h>
00022 
00023 #include <qpainter.h>
00024 #include <qcursor.h>
00025 
00026 #include "form.h"
00027 #include "formmanager.h"
00028 #include "resizehandle.h"
00029 #include "container.h"
00030 #include "widgetfactory.h"
00031 #include "widgetlibrary.h"
00032 
00033 #define MINIMUM_WIDTH 10
00034 #define MINIMUM_HEIGHT 10
00035 
00036 using namespace KFormDesigner;
00037 
00038 ResizeHandle::ResizeHandle(ResizeHandleSet *set, HandlePos pos, bool editing)
00039  : QWidget(set->m_widget->parentWidget()), m_set(set)
00040 {
00041 //  setBackgroundMode(Qt::NoBackground);
00042     m_dragging = false;
00043     //m_editing = editing;
00044     setEditingMode(editing);
00045     setFixedWidth(6);
00046     setFixedHeight(6);
00047     m_pos = pos;
00048     //m_buddy = buddy;
00049     //buddy->installEventFilter(this);
00050     m_set->m_widget->installEventFilter(this);
00051 //js    installEventFilter(this);
00052 
00053     updatePos();
00054     show();
00055 }
00056 
00057 ResizeHandle::~ResizeHandle()
00058 {
00059 }
00060 
00061 void ResizeHandle::setEditingMode(bool editing)
00062 {
00063     if(editing)
00064         setBackgroundColor(blue);
00065     else
00066         setBackgroundColor(black);
00067 }
00068 
00069 void ResizeHandle::updatePos()
00070 {
00071     switch (m_pos)
00072     {
00073         case TopLeft:
00074             move(m_set->m_widget->x() - 3, m_set->m_widget->y() - 3);
00075             setCursor(QCursor(SizeFDiagCursor));
00076             break;
00077         case TopCenter:
00078             move(m_set->m_widget->x() + m_set->m_widget->width()/2 - 3, m_set->m_widget->y() - 3);
00079             setCursor(QCursor(SizeVerCursor));
00080             break;
00081         case TopRight:
00082             move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() - 3);
00083             setCursor(QCursor(SizeBDiagCursor));
00084             break;
00085         case LeftCenter:
00086             move(m_set->m_widget->x() - 3, m_set->m_widget->y() + m_set->m_widget->height()/2 - 3);
00087             setCursor(QCursor(SizeHorCursor));
00088             break;
00089         case RightCenter:
00090             move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() + m_set->m_widget->height()/2 - 3);
00091             setCursor(QCursor(SizeHorCursor));
00092             break;
00093         case BottomLeft:
00094             move(m_set->m_widget->x() - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
00095             setCursor(QCursor(SizeBDiagCursor));
00096             break;
00097         case BottomCenter:
00098             move(m_set->m_widget->x() + m_set->m_widget->width()/2 - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
00099             setCursor(QCursor(SizeVerCursor));
00100             break;
00101         case BottomRight:
00102             move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
00103             setCursor(QCursor(SizeFDiagCursor));
00104             break;
00105     }
00106 }
00107 
00108 bool ResizeHandle::eventFilter(QObject *o, QEvent *ev)
00109 {
00110     if (((ev->type() == QEvent::Move) || (ev->type() == QEvent::Resize)) && o == m_set->m_widget)
00111     {
00112         //QTimer::singleShot(0,this,SLOT(updatePos()));
00113         updatePos();
00114     }
00115 /*  else if (ev->type() == QEvent::Paint && o == this) {
00116         QPainter p;
00117         p.begin(m_set->m_widget, true);
00118         const bool unclipped = testWFlags( WPaintUnclipped );
00119         setWFlags( WPaintUnclipped );
00120 
00121         p.setPen(QPen(white, 10));
00122         p.setRasterOp(XorROP);
00123         p.drawRect( 20, 20, 100, 100 );//m_set->m_widget->x(), m_set->m_widget->y(), 150, 150 );
00124         p.drawRect( m_set->m_widget->x(), m_set->m_widget->y(), 150, 150 );
00125         if (!unclipped)
00126             clearWFlags( WPaintUnclipped );
00127         p.end();
00128 
00129         return true;
00130     }*/
00131     return false;
00132 }
00133 
00134 void ResizeHandle::mousePressEvent(QMouseEvent *ev)
00135 {
00136     const bool startDragging = !m_dragging;
00137     m_dragging = true;
00138     m_x = ev->x();
00139     m_y = ev->y();
00140     if (startDragging) {
00141 //  m_form->resizeHandleDraggingStarted(m_set->widget());
00142         WidgetFactory *wfactory = m_set->m_form->library()->factoryForClassName(m_set->widget()->className());
00143         if (wfactory)
00144             wfactory->resetEditor();
00145     }
00146 }
00147 
00148 void ResizeHandle::mouseMoveEvent(QMouseEvent *ev)
00149 {
00150     int gridX = m_set->m_form->gridSize();
00151     int gridY = m_set->m_form->gridSize();
00152 
00153     if (!m_dragging) return;
00154     //if(m_editing)  return;
00155 
00156     int tmpx = m_set->m_widget->x();
00157     int tmpy = m_set->m_widget->y();
00158     int tmpw = m_set->m_widget->width();
00159     int tmph = m_set->m_widget->height();
00160 
00161     int dummyx = ev->x() - m_x;
00162     int dummyy = ev->y() - m_y;
00163 
00164     if(FormManager::self()->snapWidgetsToGrid() && (ev->state() != (LeftButton|ControlButton|AltButton)))
00165     {
00166         dummyy = (int) ( ((float)dummyy) / ((float)gridY) + 0.5 );
00167         dummyy *= gridY;
00168         dummyx = (int) ( ((float)dummyx) / ((float)gridX) + 0.5 );
00169         dummyx *= gridX;
00170     }
00171 
00172     switch (m_pos)
00173     {
00174         case TopRight:
00175             tmpw += dummyx;
00176             tmpy += dummyy;
00177             tmph -= dummyy;
00178             break;
00179         case RightCenter:
00180             tmpw += dummyx;
00181             break;
00182         case BottomRight:
00183             tmpw += dummyx;
00184             tmph += dummyy;
00185             break;
00186         case TopCenter:
00187             tmpy += dummyy;
00188             tmph -= dummyy;
00189             break;
00190         case BottomCenter:
00191             tmph=tmph+dummyy;
00192             break;
00193         case TopLeft:
00194             tmpx += dummyx;
00195             tmpw -= dummyx;
00196             tmpy += dummyy;
00197             tmph -= dummyy;
00198             break;
00199         case LeftCenter:
00200             tmpx += dummyx;
00201             tmpw -= dummyx;
00202             break;
00203         case BottomLeft:
00204             tmpx += dummyx;
00205             tmpw -= dummyx;
00206             tmph += dummyy;
00207             break;
00208     }
00209 
00210     // Not move the top-left corner further than the bottom-right corner
00211     if(tmpx >= m_set->m_widget->x() + m_set->m_widget->width())
00212     {
00213         tmpx = m_set->m_widget->x() + m_set->m_widget->width() - MINIMUM_WIDTH;
00214         tmpw = MINIMUM_WIDTH;
00215     }
00216 
00217     if(tmpy >= m_set->m_widget->y() + m_set->m_widget->height())
00218     {
00219         tmpy = m_set->m_widget->y() + m_set->m_widget->height() - MINIMUM_HEIGHT;
00220         tmph = MINIMUM_HEIGHT;
00221     }
00222 
00223     // Do not resize a widget outside of parent boundaries
00224     if(tmpx < 0)
00225     {
00226         tmpw += tmpx;
00227         tmpx = 0;
00228     }
00229     else if(tmpx + tmpw > m_set->m_widget->parentWidget()->width())
00230         tmpw = m_set->m_widget->parentWidget()->width() - tmpx;
00231 
00232     if(tmpy < 0)
00233     {
00234         tmph += tmpy;
00235         tmpy = 0;
00236     }
00237     else if(tmpy + tmph > m_set->m_widget->parentWidget()->height())
00238         tmph = m_set->m_widget->parentWidget()->height() - tmpy;
00239 
00240     const bool shouldBeMoved = (tmpx != m_set->m_widget->x()) || (tmpy != m_set->m_widget->y());
00241     const bool shouldBeResized = (tmpw != m_set->m_widget->width()) || (tmph != m_set->m_widget->height());
00242 
00243     if (shouldBeMoved && shouldBeResized)
00244         m_set->m_widget->hide();
00245 
00246     // Resize it
00247     if (shouldBeResized)
00248     {
00249         // Keep a QSize(10, 10) minimum size
00250         tmpw = (tmpw < MINIMUM_WIDTH) ? MINIMUM_WIDTH : tmpw;
00251         tmph = (tmph < MINIMUM_HEIGHT) ? MINIMUM_HEIGHT : tmph;
00252         m_set->m_widget->resize(tmpw,tmph);
00253     }
00254 
00255     // Move the widget if necessary
00256     if (shouldBeMoved)
00257         m_set->m_widget->move(tmpx,tmpy);
00258 
00259     if (shouldBeMoved && shouldBeResized)
00260         m_set->m_widget->show();
00261 }
00262 
00263 void ResizeHandle::mouseReleaseEvent(QMouseEvent *)
00264 {
00265     m_dragging = false;
00266 }
00267 
00268 void ResizeHandle::paintEvent( QPaintEvent * )
00269 {
00270     //draw XORed background
00271 
00272     /*QPainter p(this);
00273     p.setRasterOp(XorROP);
00274     p.fillRect(QRect(0, 0, 6, 6),white);
00275     bitBlt( this, QPoint(0,0), parentWidget(), rect(), XorROP);*/
00276 }
00277 
00279 
00280 ResizeHandleSet::ResizeHandleSet(QWidget *modify, Form *form, bool editing)
00281 : QObject(modify->parentWidget()), /*m_widget(modify),*/ m_form(form)
00282 {
00283     m_widget = 0;
00284     /*QWidget *parent = modify->parentWidget();
00285 
00286     handles[0] = new ResizeHandle( modify, ResizeHandle::TopLeft, editing);
00287     handles[1] = new ResizeHandle( modify, ResizeHandle::TopCenter, editing);
00288     handles[2] = new ResizeHandle( modify, ResizeHandle::TopRight, editing);
00289     handles[3] = new ResizeHandle( modify, ResizeHandle::LeftCenter, editing);
00290     handles[4] = new ResizeHandle( modify, ResizeHandle::RightCenter, editing);
00291     handles[5] = new ResizeHandle( modify, ResizeHandle::BottomLeft, editing);
00292     handles[6] = new ResizeHandle( modify, ResizeHandle::BottomCenter, editing);
00293     handles[7] = new ResizeHandle( modify, ResizeHandle::BottomRight, editing);*/
00294     setWidget(modify, editing);
00295 }
00296 
00297 ResizeHandleSet::~ResizeHandleSet()
00298 {
00299     for (int i = 0; i < 8; i++)
00300         delete m_handles[i];
00301 }
00302 
00303 void
00304 ResizeHandleSet::setWidget(QWidget *modify, bool editing)
00305 {
00306     if(modify == m_widget)
00307         return;
00308 
00309     if(m_widget) {
00310         for(int i = 0; i < 8; i++)
00311             delete m_handles[i];
00312     }
00313 
00314     m_widget = modify;
00315 
00316     m_handles[0] = new ResizeHandle(this, ResizeHandle::TopLeft, editing);
00317     m_handles[1] = new ResizeHandle(this, ResizeHandle::TopCenter, editing);
00318     m_handles[2] = new ResizeHandle(this, ResizeHandle::TopRight, editing);
00319     m_handles[3] = new ResizeHandle(this, ResizeHandle::LeftCenter, editing);
00320     m_handles[4] = new ResizeHandle(this, ResizeHandle::RightCenter, editing);
00321     m_handles[5] = new ResizeHandle(this, ResizeHandle::BottomLeft, editing);
00322     m_handles[6] = new ResizeHandle(this, ResizeHandle::BottomCenter, editing);
00323     m_handles[7] = new ResizeHandle(this, ResizeHandle::BottomRight, editing);
00324 }
00325 
00326 void
00327 ResizeHandleSet::raise()
00328 {
00329     for(int i = 0; i < 8; i++)
00330         m_handles[i]->raise();
00331 }
00332 
00333 void ResizeHandleSet::setEditingMode(bool editing)
00334 {
00335     for(int i = 0; i < 8; i++)
00336         m_handles[i]->setEditingMode(editing);
00337 }
00338 
00339 #include "resizehandle.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys