kexi

resizehandle.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
3 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <kdebug.h>
21#include <tdelocale.h>
22
23#include <tqpainter.h>
24#include <tqcursor.h>
25
26#include "form.h"
27#include "formmanager.h"
28#include "resizehandle.h"
29#include "container.h"
30#include "widgetfactory.h"
31#include "widgetlibrary.h"
32
33#define MINIMUM_WIDTH 10
34#define MINIMUM_HEIGHT 10
35
36using namespace KFormDesigner;
37
38ResizeHandle::ResizeHandle(ResizeHandleSet *set, HandlePos pos, bool editing)
39 : TQWidget(set->m_widget->parentWidget()), m_set(set)
40{
41// setBackgroundMode(TQt::NoBackground);
42 m_dragging = false;
43 //m_editing = editing;
44 setEditingMode(editing);
45 setFixedWidth(6);
46 setFixedHeight(6);
47 m_pos = pos;
48 //m_buddy = buddy;
49 //buddy->installEventFilter(this);
50 m_set->m_widget->installEventFilter(this);
51//js installEventFilter(this);
52
53 updatePos();
54 show();
55}
56
57ResizeHandle::~ResizeHandle()
58{
59}
60
61void ResizeHandle::setEditingMode(bool editing)
62{
63 if(editing)
64 setBackgroundColor(blue);
65 else
66 setBackgroundColor(black);
67}
68
69void ResizeHandle::updatePos()
70{
71 switch (m_pos)
72 {
73 case TopLeft:
74 move(m_set->m_widget->x() - 3, m_set->m_widget->y() - 3);
75 setCursor(TQCursor(SizeFDiagCursor));
76 break;
77 case TopCenter:
78 move(m_set->m_widget->x() + m_set->m_widget->width()/2 - 3, m_set->m_widget->y() - 3);
79 setCursor(TQCursor(SizeVerCursor));
80 break;
81 case TopRight:
82 move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() - 3);
83 setCursor(TQCursor(SizeBDiagCursor));
84 break;
85 case LeftCenter:
86 move(m_set->m_widget->x() - 3, m_set->m_widget->y() + m_set->m_widget->height()/2 - 3);
87 setCursor(TQCursor(SizeHorCursor));
88 break;
89 case RightCenter:
90 move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() + m_set->m_widget->height()/2 - 3);
91 setCursor(TQCursor(SizeHorCursor));
92 break;
93 case BottomLeft:
94 move(m_set->m_widget->x() - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
95 setCursor(TQCursor(SizeBDiagCursor));
96 break;
97 case BottomCenter:
98 move(m_set->m_widget->x() + m_set->m_widget->width()/2 - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
99 setCursor(TQCursor(SizeVerCursor));
100 break;
101 case BottomRight:
102 move(m_set->m_widget->x() + m_set->m_widget->width() - 3, m_set->m_widget->y() + m_set->m_widget->height() - 3);
103 setCursor(TQCursor(SizeFDiagCursor));
104 break;
105 }
106}
107
108bool ResizeHandle::eventFilter(TQObject *o, TQEvent *ev)
109{
110 if (((ev->type() == TQEvent::Move) || (ev->type() == TQEvent::Resize)) && o == m_set->m_widget)
111 {
112 //TQTimer::singleShot(0,this,TQ_SLOT(updatePos()));
113 updatePos();
114 }
115/* else if (ev->type() == TQEvent::Paint && o == this) {
116 TQPainter p;
117 p.begin(m_set->m_widget, true);
118 const bool unclipped = testWFlags( WPaintUnclipped );
119 setWFlags( WPaintUnclipped );
120
121 p.setPen(TQPen(white, 10));
122 p.setRasterOp(XorROP);
123 p.drawRect( 20, 20, 100, 100 );//m_set->m_widget->x(), m_set->m_widget->y(), 150, 150 );
124 p.drawRect( m_set->m_widget->x(), m_set->m_widget->y(), 150, 150 );
125 if (!unclipped)
126 clearWFlags( WPaintUnclipped );
127 p.end();
128
129 return true;
130 }*/
131 return false;
132}
133
134void ResizeHandle::mousePressEvent(TQMouseEvent *ev)
135{
136 const bool startDragging = !m_dragging;
137 m_dragging = true;
138 m_x = ev->x();
139 m_y = ev->y();
140 if (startDragging) {
141// m_form->resizeHandleDraggingStarted(m_set->widget());
142 WidgetFactory *wfactory = m_set->m_form->library()->factoryForClassName(m_set->widget()->className());
143 if (wfactory)
144 wfactory->resetEditor();
145 }
146}
147
148void ResizeHandle::mouseMoveEvent(TQMouseEvent *ev)
149{
150 int gridX = m_set->m_form->gridSize();
151 int gridY = m_set->m_form->gridSize();
152
153 if (!m_dragging) return;
154 //if(m_editing) return;
155
156 int tmpx = m_set->m_widget->x();
157 int tmpy = m_set->m_widget->y();
158 int tmpw = m_set->m_widget->width();
159 int tmph = m_set->m_widget->height();
160
161 int dummyx = ev->x() - m_x;
162 int dummyy = ev->y() - m_y;
163
164 if(FormManager::self()->snapWidgetsToGrid() && (ev->state() != (TQt::LeftButton|TQt::ControlButton|TQt::AltButton)))
165 {
166 dummyy = (int) ( ((float)dummyy) / ((float)gridY) + 0.5 );
167 dummyy *= gridY;
168 dummyx = (int) ( ((float)dummyx) / ((float)gridX) + 0.5 );
169 dummyx *= gridX;
170 }
171
172 switch (m_pos)
173 {
174 case TopRight:
175 tmpw += dummyx;
176 tmpy += dummyy;
177 tmph -= dummyy;
178 break;
179 case RightCenter:
180 tmpw += dummyx;
181 break;
182 case BottomRight:
183 tmpw += dummyx;
184 tmph += dummyy;
185 break;
186 case TopCenter:
187 tmpy += dummyy;
188 tmph -= dummyy;
189 break;
190 case BottomCenter:
191 tmph=tmph+dummyy;
192 break;
193 case TopLeft:
194 tmpx += dummyx;
195 tmpw -= dummyx;
196 tmpy += dummyy;
197 tmph -= dummyy;
198 break;
199 case LeftCenter:
200 tmpx += dummyx;
201 tmpw -= dummyx;
202 break;
203 case BottomLeft:
204 tmpx += dummyx;
205 tmpw -= dummyx;
206 tmph += dummyy;
207 break;
208 }
209
210 // Not move the top-left corner further than the bottom-right corner
211 if(tmpx >= m_set->m_widget->x() + m_set->m_widget->width())
212 {
213 tmpx = m_set->m_widget->x() + m_set->m_widget->width() - MINIMUM_WIDTH;
214 tmpw = MINIMUM_WIDTH;
215 }
216
217 if(tmpy >= m_set->m_widget->y() + m_set->m_widget->height())
218 {
219 tmpy = m_set->m_widget->y() + m_set->m_widget->height() - MINIMUM_HEIGHT;
220 tmph = MINIMUM_HEIGHT;
221 }
222
223 // Do not resize a widget outside of parent boundaries
224 if(tmpx < 0)
225 {
226 tmpw += tmpx;
227 tmpx = 0;
228 }
229 else if(tmpx + tmpw > m_set->m_widget->parentWidget()->width())
230 tmpw = m_set->m_widget->parentWidget()->width() - tmpx;
231
232 if(tmpy < 0)
233 {
234 tmph += tmpy;
235 tmpy = 0;
236 }
237 else if(tmpy + tmph > m_set->m_widget->parentWidget()->height())
238 tmph = m_set->m_widget->parentWidget()->height() - tmpy;
239
240 const bool shouldBeMoved = (tmpx != m_set->m_widget->x()) || (tmpy != m_set->m_widget->y());
241 const bool shouldBeResized = (tmpw != m_set->m_widget->width()) || (tmph != m_set->m_widget->height());
242
243 if (shouldBeMoved && shouldBeResized)
244 m_set->m_widget->hide();
245
246 // Resize it
247 if (shouldBeResized)
248 {
249 // Keep a TQSize(10, 10) minimum size
250 tmpw = (tmpw < MINIMUM_WIDTH) ? MINIMUM_WIDTH : tmpw;
251 tmph = (tmph < MINIMUM_HEIGHT) ? MINIMUM_HEIGHT : tmph;
252 m_set->m_widget->resize(tmpw,tmph);
253 }
254
255 // Move the widget if necessary
256 if (shouldBeMoved)
257 m_set->m_widget->move(tmpx,tmpy);
258
259 if (shouldBeMoved && shouldBeResized)
260 m_set->m_widget->show();
261}
262
263void ResizeHandle::mouseReleaseEvent(TQMouseEvent *)
264{
265 m_dragging = false;
266}
267
268void ResizeHandle::paintEvent( TQPaintEvent * )
269{
270 //draw XORed background
271
272 /*TQPainter p(this);
273 p.setRasterOp(XorROP);
274 p.fillRect(TQRect(0, 0, 6, 6),white);
275 bitBlt( this, TQPoint(0,0), parentWidget(), rect(), XorROP);*/
276}
277
279
280ResizeHandleSet::ResizeHandleSet(TQWidget *modify, Form *form, bool editing)
281: TQObject(modify->parentWidget()), /*m_widget(modify),*/ m_form(form)
282{
283 m_widget = 0;
284 /*TQWidget *parent = modify->parentWidget();
285
286 handles[0] = new ResizeHandle( modify, ResizeHandle::TopLeft, editing);
287 handles[1] = new ResizeHandle( modify, ResizeHandle::TopCenter, editing);
288 handles[2] = new ResizeHandle( modify, ResizeHandle::TopRight, editing);
289 handles[3] = new ResizeHandle( modify, ResizeHandle::LeftCenter, editing);
290 handles[4] = new ResizeHandle( modify, ResizeHandle::RightCenter, editing);
291 handles[5] = new ResizeHandle( modify, ResizeHandle::BottomLeft, editing);
292 handles[6] = new ResizeHandle( modify, ResizeHandle::BottomCenter, editing);
293 handles[7] = new ResizeHandle( modify, ResizeHandle::BottomRight, editing);*/
294 setWidget(modify, editing);
295}
296
297ResizeHandleSet::~ResizeHandleSet()
298{
299 for (int i = 0; i < 8; i++)
300 delete m_handles[i];
301}
302
303void
304ResizeHandleSet::setWidget(TQWidget *modify, bool editing)
305{
306 if(modify == m_widget)
307 return;
308
309 if(m_widget) {
310 for(int i = 0; i < 8; i++)
311 delete m_handles[i];
312 }
313
314 m_widget = modify;
315
316 m_handles[0] = new ResizeHandle(this, ResizeHandle::TopLeft, editing);
317 m_handles[1] = new ResizeHandle(this, ResizeHandle::TopCenter, editing);
318 m_handles[2] = new ResizeHandle(this, ResizeHandle::TopRight, editing);
319 m_handles[3] = new ResizeHandle(this, ResizeHandle::LeftCenter, editing);
320 m_handles[4] = new ResizeHandle(this, ResizeHandle::RightCenter, editing);
321 m_handles[5] = new ResizeHandle(this, ResizeHandle::BottomLeft, editing);
322 m_handles[6] = new ResizeHandle(this, ResizeHandle::BottomCenter, editing);
323 m_handles[7] = new ResizeHandle(this, ResizeHandle::BottomRight, editing);
324}
325
326void
327ResizeHandleSet::raise()
328{
329 for(int i = 0; i < 8; i++)
330 m_handles[i]->raise();
331}
332
333void ResizeHandleSet::setEditingMode(bool editing)
334{
335 for(int i = 0; i < 8; i++)
336 m_handles[i]->setEditingMode(editing);
337}
338
339#include "resizehandle.moc"
static FormManager * self()
Access to FormManager singleton.
A simple class representing a form.
Definition form.h:136
a set of resize handles (for resizing widgets)