38 #include "hbstyleoption_p.h" |
38 #include "hbstyleoption_p.h" |
39 #include "hbeffect.h" |
39 #include "hbeffect.h" |
40 #include "hbdialog_p.h" |
40 #include "hbdialog_p.h" |
41 #include "hbabstractedit.h" |
41 #include "hbabstractedit.h" |
42 #include "hbabstractedit_p.h" |
42 #include "hbabstractedit_p.h" |
|
43 #include "hblineedit.h" |
43 #include "hbtoucharea.h" |
44 #include "hbtoucharea.h" |
44 #include "hbpangesture.h" |
45 #include "hbpangesture.h" |
45 #include "hbtapgesture.h" |
46 #include "hbtapgesture.h" |
46 #include "hbevent.h" |
47 #include "hbevent.h" |
47 #include "hbpopup.h" |
48 #include "hbpopup.h" |
|
49 #include "hbmagnifier_p.h" |
48 #include "hbnamespace_p.h" |
50 #include "hbnamespace_p.h" |
49 #include "hbmainwindow.h" |
51 #include "hbmainwindow.h" |
|
52 #include "hbdeviceprofile.h" |
|
53 #include "hbiconitem.h" |
50 |
54 |
51 |
55 |
52 #include <QTextCursor> |
56 #include <QTextCursor> |
|
57 #include <QTextBlock> |
53 #include <QGraphicsItem> |
58 #include <QGraphicsItem> |
|
59 #include <QGraphicsWidget> |
54 #include <QAbstractTextDocumentLayout> |
60 #include <QAbstractTextDocumentLayout> |
55 #include <QGraphicsSceneMouseEvent> |
61 #include <QGraphicsSceneMouseEvent> |
56 #include <QBasicTimer> |
62 #include <QBasicTimer> |
57 #include <QSizeF> |
63 #include <QSizeF> |
58 #include <QPointF> |
64 #include <QPointF> |
59 #include <QHash> |
65 #include <QHash> |
60 #include <QGraphicsScene> |
66 #include <QGraphicsScene> |
61 |
67 |
62 #include <hbwidgetfeedback.h> |
68 #include <hbwidgetfeedback.h> |
63 |
69 |
|
70 |
|
71 #define HB_DEBUG_PAINT_INFO 0 |
|
72 |
64 typedef QHash<HbMainWindow*,HbSelectionControl*> HbSelectionControlHash; |
73 typedef QHash<HbMainWindow*,HbSelectionControl*> HbSelectionControlHash; |
65 Q_GLOBAL_STATIC(HbSelectionControlHash, globalSelectionControlHash) |
74 Q_GLOBAL_STATIC(HbSelectionControlHash, globalSelectionControlHash) |
66 |
75 |
67 namespace { |
76 namespace { |
68 static const int SNAP_DELAY = 300; |
77 static const int SNAP_DELAY = 300; |
69 } |
78 static const int MAGNIFIER_OPEN_DELAY = 200; |
|
79 static const qreal MAGNIFIER_SCALE_FACTOR = 1.5; |
|
80 } |
|
81 |
|
82 class MyEditor: public HbAbstractEdit |
|
83 { |
|
84 public: |
|
85 using HbAbstractEdit::drawContents; |
|
86 }; |
|
87 |
|
88 |
|
89 class HbMagnifierDelegateEditor : public HbMagnifierDelegate |
|
90 { |
|
91 public: |
|
92 HbMagnifierDelegateEditor(HbAbstractEdit * editor) {this->editor = editor;} |
|
93 virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) |
|
94 { |
|
95 if (option && editor) { |
|
96 static_cast<MyEditor*>(editor)->drawContents(painter,*option); |
|
97 } |
|
98 } |
|
99 void setEditor(HbAbstractEdit * editor){this->editor = editor;} |
|
100 private: |
|
101 HbAbstractEdit * editor; |
|
102 }; |
70 |
103 |
71 |
104 |
72 class HbSelectionControlPrivate :public HbDialogPrivate |
105 class HbSelectionControlPrivate :public HbDialogPrivate |
73 { |
106 { |
74 Q_DECLARE_PUBLIC(HbSelectionControl) |
107 Q_DECLARE_PUBLIC(HbSelectionControl) |
75 |
108 |
76 public: |
109 public: |
|
110 enum InteractionMode { |
|
111 Selection, |
|
112 CursorPositioning |
|
113 }; |
|
114 |
|
115 enum HandleType { |
|
116 DummyHandle, |
|
117 SelectionStartHandle, |
|
118 SelectionEndHandle |
|
119 }; |
|
120 |
|
121 |
77 HbSelectionControlPrivate(); |
122 HbSelectionControlPrivate(); |
|
123 ~HbSelectionControlPrivate(); |
78 void init(); |
124 void init(); |
79 void createPrimitives(); |
125 void createPrimitives(); |
80 void updateHandle(int newHandlePos, |
126 void updateHandle(int cursorPos, |
|
127 int newHandlePos, |
81 Qt::AlignmentFlag handleAlignment, |
128 Qt::AlignmentFlag handleAlignment, |
82 QGraphicsItem *handle, |
129 QGraphicsItem *handle, |
83 QGraphicsItem *handleTouchArea, |
130 QGraphicsItem *handleTouchArea); |
84 HbStyle::Primitive handlePrimitive); |
131 void updateMagnifier(); |
|
132 void initMagnifier(); |
|
133 |
85 QGraphicsItem * reparent(QGraphicsItem *item); |
134 QGraphicsItem * reparent(QGraphicsItem *item); |
86 void reparent(QGraphicsItem *item, QGraphicsItem *newParent); |
135 void reparent(QGraphicsItem *item, QGraphicsItem *newParent); |
87 void reparentHandles(QGraphicsItem *newParent); |
136 void reparentHandles(QGraphicsItem *newParent); |
88 void tapGestureFinished (const QPointF& point); |
137 QPointF constrainHitTestPoint(const QPointF& point); |
|
138 HbSelectionControlPrivate::HandleType handleForPoint(const QPointF& point); |
|
139 void gestureStarted(const QPointF &point); |
|
140 void tapGestureStarted(HbTapGesture *gesture); |
|
141 void tapGestureFinished(); |
|
142 void delayedTapFinished(); |
89 void panGestureStarted (HbPanGesture *gesture); |
143 void panGestureStarted (HbPanGesture *gesture); |
90 void panGestureUpdated (HbPanGesture *gesture); |
144 void panGestureUpdated (HbPanGesture *gesture); |
91 void panGestureFinished (HbPanGesture *gesture); |
145 void panGestureFinished (HbPanGesture *gesture); |
|
146 void panGestureCanceled(); |
92 void show(); |
147 void show(); |
93 void _q_aboutToChangeView(); |
148 void _q_aboutToChangeView(); |
94 void detachEditor(bool updateAtthachedEditorState); |
149 void detachEditor(bool updateAtthachedEditorState); |
95 |
150 |
|
151 #if HB_DEBUG_PAINT_INFO |
|
152 void updateDebugPaintInfo(); |
|
153 #endif |
|
154 |
|
155 |
96 public: |
156 public: |
97 |
157 |
98 HbAbstractEdit *mEdit; |
158 HbAbstractEdit *mEdit; |
99 QGraphicsItem *mTopLevelAncestor; |
159 HbMagnifierDelegateEditor *mMagnifierDelegate; // Owned by mMagnifier |
100 |
160 HbMagnifier* mMagnifier; |
101 QGraphicsItem *mSelectionStartHandle; |
161 |
102 QGraphicsItem *mSelectionEndHandle; |
162 QGraphicsItem *mTopLevelAncestor; |
|
163 // The offset between the gesture start point and first hit test point |
|
164 QPointF mTouchOffsetFromHitTestPoint; |
|
165 |
|
166 HbIconItem *mSelectionStartHandle; |
|
167 HbIconItem *mSelectionEndHandle; |
103 HbTouchArea* mSelectionStartTouchArea; |
168 HbTouchArea* mSelectionStartTouchArea; |
104 HbTouchArea* mSelectionEndTouchArea; |
169 HbTouchArea* mSelectionEndTouchArea; |
105 |
170 |
106 HbSelectionControl::HandleType mPressed; |
171 InteractionMode mInteractionMode; |
107 bool mPanInProgress; |
172 HandleType mPressed; |
|
173 bool mScrollInProgress; |
|
174 QPointF mHitTestPoint; // HbSelectionControl's coordinate system |
|
175 QPointF mTouchPoint; // HbSelectionControl's coordinate system |
|
176 QPointF mStartHandleHitTestPoint; // HbSelectionControl's coordinate system |
|
177 QPointF mEndHandleHitTestPoint; // HbSelectionControl's coordinate system |
108 QBasicTimer mWordSnapTimer; |
178 QBasicTimer mWordSnapTimer; |
|
179 QBasicTimer mDelayedTapTimer; |
|
180 |
|
181 bool mMagnifierEnabled; |
|
182 qreal mLastCursorHeight; |
|
183 qreal mHandleMarginFromLine; |
|
184 qreal mMagnifierMarginFromLine; |
|
185 qreal mMagnifierLeftRightMarginFromHandle; |
|
186 qreal mMagnifierMaxDescent; |
|
187 qreal mVerticalScreenMargin; |
|
188 qreal mTouchYOffsetFromMagnifierReferenceLine; // HbSelectionControl's coordinate system |
|
189 qreal mStartHandleMagnifierReferenceLine; // HbSelectionControl's coordinate system |
|
190 qreal mEndHandleMagnifierReferenceLine; // HbSelectionControl's coordinate system |
|
191 qreal mMagnifierMaxYOffsetFromTouchPoint; |
|
192 qreal mMagnifierMinYOffsetFromTouchPoint; |
|
193 qreal mMaxHitTestPointOffsetYFromLine; |
|
194 bool mIsPanActive; |
|
195 |
|
196 #if HB_DEBUG_PAINT_INFO |
|
197 QRectF mDocRectDebug; // HbSelectionControl's coordinate system |
|
198 #endif |
109 }; |
199 }; |
110 |
200 |
111 |
201 |
112 HbSelectionControlPrivate::HbSelectionControlPrivate(): |
202 HbSelectionControlPrivate::HbSelectionControlPrivate(): |
113 mEdit(0), |
203 mEdit(0), |
|
204 mMagnifierDelegate(0), |
|
205 mMagnifier(0), |
114 mTopLevelAncestor(0), |
206 mTopLevelAncestor(0), |
115 mSelectionStartHandle(0), |
207 mSelectionStartHandle(0), |
116 mSelectionEndHandle(0), |
208 mSelectionEndHandle(0), |
117 mSelectionStartTouchArea(0), |
209 mSelectionStartTouchArea(0), |
118 mSelectionEndTouchArea(0), |
210 mSelectionEndTouchArea(0), |
119 mPressed(HbSelectionControl::HandleType(0)), |
211 mInteractionMode(InteractionMode(0)), |
120 mPanInProgress(false) |
212 mPressed(HandleType(0)), |
|
213 mScrollInProgress(false), |
|
214 mMagnifierEnabled(true), |
|
215 mLastCursorHeight(0.0), |
|
216 mHandleMarginFromLine(0.0), |
|
217 mMagnifierMarginFromLine(0.0), |
|
218 mMagnifierLeftRightMarginFromHandle(0.0), |
|
219 mMagnifierMaxDescent(0.0), |
|
220 mVerticalScreenMargin(0.0), |
|
221 mTouchYOffsetFromMagnifierReferenceLine(0.0), |
|
222 mStartHandleMagnifierReferenceLine(0.0), |
|
223 mEndHandleMagnifierReferenceLine(0.0), |
|
224 mMagnifierMaxYOffsetFromTouchPoint(0.0), |
|
225 mMagnifierMinYOffsetFromTouchPoint(0.0), |
|
226 mMaxHitTestPointOffsetYFromLine(0.0), |
|
227 mIsPanActive(false) |
121 { |
228 { |
122 } |
229 } |
123 |
230 |
|
231 HbSelectionControlPrivate::~HbSelectionControlPrivate() |
|
232 { |
|
233 } |
|
234 |
124 void HbSelectionControlPrivate::init() |
235 void HbSelectionControlPrivate::init() |
125 { |
236 { |
126 Q_Q(HbSelectionControl); |
237 Q_Q(HbSelectionControl); |
|
238 |
|
239 // Set the size of the control to 0 |
|
240 q->resize(0,0); |
|
241 |
|
242 #if HB_DEBUG_PAINT_INFO |
|
243 // Override 0 size to be able to paint paint |
|
244 q->resize(1,1); |
|
245 #endif |
|
246 |
|
247 q->style()->parameter(QLatin1String("hb-param-margin-gene-middle-vertical"), mVerticalScreenMargin); |
|
248 |
127 createPrimitives(); |
249 createPrimitives(); |
128 |
250 |
129 q->setVisible(false); |
251 q->setVisible(false); |
130 QGraphicsItem::GraphicsItemFlags itemFlags = q->flags(); |
252 QGraphicsItem::GraphicsItemFlags itemFlags = q->flags(); |
131 #if QT_VERSION >= 0x040600 |
253 #if QT_VERSION >= 0x040600 |
134 itemFlags &= ~QGraphicsItem::ItemIsFocusable; |
256 itemFlags &= ~QGraphicsItem::ItemIsFocusable; |
135 itemFlags |= QGraphicsItem::ItemIsPanel; |
257 itemFlags |= QGraphicsItem::ItemIsPanel; |
136 q->setFlags(itemFlags); |
258 q->setFlags(itemFlags); |
137 q->setFocusPolicy(Qt::NoFocus); |
259 q->setFocusPolicy(Qt::NoFocus); |
138 q->setActive(false); |
260 q->setActive(false); |
139 |
|
140 // Control will handle all events going to different handlers. |
|
141 q->setHandlesChildEvents(true); |
|
142 } |
261 } |
143 |
262 |
144 void HbSelectionControlPrivate::createPrimitives() |
263 void HbSelectionControlPrivate::createPrimitives() |
145 { |
264 { |
146 Q_Q(HbSelectionControl); |
265 Q_Q(HbSelectionControl); |
147 if (!mSelectionStartHandle) { |
266 if (!mSelectionStartHandle) { |
148 mSelectionStartHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionstart, q); |
267 |
|
268 mSelectionStartHandle = new HbIconItem(q); |
|
269 mSelectionStartHandle->setIconName(QLatin1String("qtg_graf_editor_handle_begin")); |
|
270 HbStyle::setItemName(mSelectionStartHandle, QLatin1String("handle-icon")); |
149 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsPanel); |
271 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsPanel); |
150 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
272 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
151 mSelectionStartHandle->setActive(false); |
273 mSelectionStartHandle->setActive(false); |
152 } |
274 } |
153 |
275 |
154 if (!mSelectionEndHandle) { |
276 if (!mSelectionEndHandle) { |
155 mSelectionEndHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionend, q); |
277 mSelectionEndHandle = new HbIconItem(q); |
|
278 mSelectionEndHandle->setIconName(QLatin1String("qtg_graf_editor_handle_end")); |
|
279 HbStyle::setItemName(mSelectionEndHandle, QLatin1String("handle-icon")); |
156 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsPanel); |
280 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsPanel); |
157 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
281 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
158 mSelectionEndHandle->setActive(false); |
282 mSelectionEndHandle->setActive(false); |
159 } |
283 } |
160 |
284 |
161 if (!mSelectionStartTouchArea) { |
285 if (!mSelectionStartTouchArea) { |
162 mSelectionStartTouchArea = new HbTouchArea(q); |
286 mSelectionStartTouchArea = new HbTouchArea(q); |
163 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
287 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
164 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
288 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
165 mSelectionStartTouchArea->setActive(false); |
289 mSelectionStartTouchArea->setActive(false); |
166 HbStyle::setItemName(mSelectionStartTouchArea, "handle-toucharea"); |
290 HbStyle::setItemName(mSelectionStartTouchArea, QLatin1String("handle-toucharea")); |
167 mSelectionStartTouchArea->grabGesture(Qt::TapGesture); |
291 mSelectionStartTouchArea->grabGesture(Qt::TapGesture); |
168 mSelectionStartTouchArea->grabGesture(Qt::PanGesture); |
292 mSelectionStartTouchArea->grabGesture(Qt::PanGesture); |
|
293 mSelectionStartTouchArea->installEventFilter(q); |
169 } |
294 } |
170 |
295 |
171 if (!mSelectionEndTouchArea) { |
296 if (!mSelectionEndTouchArea) { |
172 mSelectionEndTouchArea = new HbTouchArea(q); |
297 mSelectionEndTouchArea = new HbTouchArea(q); |
173 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
298 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
174 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
299 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
175 mSelectionEndTouchArea->setActive(false); |
300 mSelectionEndTouchArea->setActive(false); |
176 HbStyle::setItemName(mSelectionEndTouchArea, "handle-toucharea"); |
301 HbStyle::setItemName(mSelectionEndTouchArea, QLatin1String("handle-toucharea")); |
177 mSelectionEndTouchArea->grabGesture(Qt::TapGesture); |
302 mSelectionEndTouchArea->grabGesture(Qt::TapGesture); |
178 mSelectionEndTouchArea->grabGesture(Qt::PanGesture); |
303 mSelectionEndTouchArea->grabGesture(Qt::PanGesture); |
|
304 mSelectionEndTouchArea->installEventFilter(q); |
|
305 } |
|
306 if(!mMagnifier) { |
|
307 mMagnifier = new HbMagnifier(q); |
|
308 mMagnifier->setFlag(QGraphicsItem::ItemIsPanel); |
|
309 mMagnifier->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
310 mMagnifier->setActive(false); |
|
311 HbStyle::setItemName(mMagnifier, QLatin1String("magnifier")); |
|
312 mMagnifierDelegate = new HbMagnifierDelegateEditor(mEdit); |
|
313 mMagnifier->setContentDelegate(mMagnifierDelegate); |
|
314 mMagnifier->hide(); |
|
315 initMagnifier(); |
179 } |
316 } |
180 } |
317 } |
181 |
318 |
182 /* |
319 /* |
183 Updates given handle associated with handleTouchArea to place it |
320 Updates given handle associated with handleTouchArea to place it |
184 newHandlePos in the selected text. |
321 newHandlePos in the selected text. |
185 handlePrimitive identifies handle graphics. |
|
186 */ |
322 */ |
187 void HbSelectionControlPrivate::updateHandle(int newHandlePos, |
323 void HbSelectionControlPrivate::updateHandle( |
|
324 int cursorPos, |
|
325 int newHandlePos, |
188 Qt::AlignmentFlag handleAlignment, |
326 Qt::AlignmentFlag handleAlignment, |
189 QGraphicsItem *handle, |
327 QGraphicsItem *handle, |
190 QGraphicsItem *handleTouchArea, |
328 QGraphicsItem *handleTouchArea) |
191 HbStyle::Primitive handlePrimitive) |
|
192 { |
329 { |
193 Q_Q(HbSelectionControl); |
330 Q_Q(HbSelectionControl); |
194 |
331 |
195 HbStyleOption option; |
332 QRectF rect = mEdit->rectForPosition(newHandlePos,(Qt::AlignTop||mInteractionMode == CursorPositioning)? |
196 |
333 QTextLine::Leading:QTextLine::Trailing); |
197 q->initStyleOption(&option); |
334 qreal lineHeight = rect.height(); |
198 mEdit->style()->updatePrimitive(handle, handlePrimitive, &option); |
335 |
199 |
336 if(cursorPos == newHandlePos) { |
200 QRectF rect = mEdit->rectForPosition(newHandlePos,Qt::AlignTop?QTextLine::Leading:QTextLine::Trailing); |
337 mLastCursorHeight = lineHeight; |
|
338 } |
|
339 |
|
340 // Store the current hit test point for the given handle |
|
341 // Convert rect to HbSelectionControl's coordinate system |
|
342 QRectF rectInSelectionControlCoord = q->mapRectFromItem(mEdit,rect); |
|
343 |
|
344 if (handleAlignment == Qt::AlignTop) { |
|
345 mStartHandleHitTestPoint = rectInSelectionControlCoord.center(); |
|
346 mStartHandleHitTestPoint.setY(qMin(mStartHandleHitTestPoint.y(), |
|
347 rectInSelectionControlCoord.top()+mMaxHitTestPointOffsetYFromLine)); |
|
348 mStartHandleMagnifierReferenceLine = rectInSelectionControlCoord.top(); |
|
349 } else { |
|
350 mEndHandleHitTestPoint = rectInSelectionControlCoord.center(); |
|
351 mEndHandleHitTestPoint.setY(qMax(mEndHandleHitTestPoint.y(), |
|
352 rectInSelectionControlCoord.bottom()-mMaxHitTestPointOffsetYFromLine)); |
|
353 mEndHandleMagnifierReferenceLine = rectInSelectionControlCoord.bottom(); |
|
354 } |
201 |
355 |
202 // Convert rect to handle's parent coordinate system |
356 // Convert rect to handle's parent coordinate system |
203 rect = handle->parentItem()->mapRectFromItem(mEdit,rect); |
357 rect = handle->parentItem()->mapRectFromItem(mEdit,rect); |
204 |
358 |
205 // Center handle around center point of rect |
359 // Center handle around center point of rect |
206 QRectF boundingRect = handle->boundingRect(); |
360 QRectF boundingRect = handle->boundingRect(); |
207 |
361 |
|
362 bool positionHandlesTouchEachOther = (boundingRect.height()*2 > lineHeight); |
|
363 |
208 boundingRect.moveCenter(rect.center()); |
364 boundingRect.moveCenter(rect.center()); |
209 |
365 |
|
366 // Position handle either on top of rect using margin mHandleMarginFromLine or so that |
|
367 // the two handles touch eachother |
210 if (handleAlignment == Qt::AlignTop) { |
368 if (handleAlignment == Qt::AlignTop) { |
211 boundingRect.moveBottom(rect.top()); |
369 if (positionHandlesTouchEachOther) { |
|
370 boundingRect.moveBottom(rect.center().y()); |
|
371 } else { |
|
372 boundingRect.moveTop(rect.top()-mHandleMarginFromLine); |
|
373 } |
212 } else { |
374 } else { |
213 boundingRect.moveTop(rect.bottom()); |
375 if (positionHandlesTouchEachOther) { |
|
376 boundingRect.moveTop(rect.center().y()); |
|
377 } else { |
|
378 boundingRect.moveBottom(rect.bottom()+mHandleMarginFromLine); |
|
379 } |
214 } |
380 } |
215 |
381 |
216 handle->setPos(boundingRect.topLeft()); |
382 handle->setPos(boundingRect.topLeft()); |
217 |
383 |
218 // Center handle touch area around center pos of handle |
384 // Position handle touch area around center-top of handle |
219 QPointF centerPos = boundingRect.center(); |
385 QPointF centerPos = boundingRect.center(); |
|
386 rect = boundingRect; |
220 boundingRect = handleTouchArea->boundingRect(); |
387 boundingRect = handleTouchArea->boundingRect(); |
221 boundingRect.moveCenter(centerPos); |
388 boundingRect.moveCenter(centerPos); |
|
389 |
|
390 if (handleAlignment != Qt::AlignTop) { |
|
391 boundingRect.moveTop(rect.top()); |
|
392 } |
|
393 |
222 handleTouchArea->setPos(boundingRect.topLeft()); |
394 handleTouchArea->setPos(boundingRect.topLeft()); |
223 |
395 |
224 if (!mPanInProgress) { |
396 if (!mScrollInProgress) { |
225 QGraphicsItem * newParent = reparent(handle); |
397 QGraphicsItem * newParent = reparent(handle); |
226 reparent(handleTouchArea, newParent); |
398 reparent(handleTouchArea, newParent); |
227 } |
399 } |
228 } |
400 } |
229 |
401 |
|
402 |
|
403 void HbSelectionControlPrivate::updateMagnifier() |
|
404 { |
|
405 Q_Q(HbSelectionControl); |
|
406 |
|
407 if (mMagnifier->isVisible()) { |
|
408 QPointF canvasHitTestPos = q->mapToItem(HbAbstractEditPrivate::d_ptr(mEdit)->canvas,mHitTestPoint); |
|
409 QRectF canvasCursorRect = HbAbstractEditPrivate::d_ptr(mEdit)->rectForPositionInCanvasCoords(mEdit->textCursor().position(),QTextLine::Leading); |
|
410 QPointF centerOfMagnification = canvasCursorRect.center(); |
|
411 centerOfMagnification.setX(canvasHitTestPos.x()); |
|
412 canvasCursorRect.moveCenter(centerOfMagnification); |
|
413 |
|
414 // Set the visible content to be magnified |
|
415 qreal magnifierHeight = mMagnifier->boundingRect().height(); |
|
416 |
|
417 // Check if the line fits vertically to the magnifier if not align the bottom of the line with the bottom of the |
|
418 // magnifier constraining a maximum line descent. |
|
419 if (magnifierHeight < canvasCursorRect.height()*mMagnifier->contentScale()) { |
|
420 const QTextCursor cursor = mEdit->textCursor(); |
|
421 const QTextBlock block = cursor.block(); |
|
422 const int positionInBlock = cursor.position() - block.position(); |
|
423 QTextLine line = block.layout()->lineForTextPosition(positionInBlock); |
|
424 qreal lineDescent = line.descent(); |
|
425 qreal lineBottom = canvasCursorRect.bottom(); |
|
426 if (mMagnifierMaxDescent < lineDescent) { |
|
427 lineBottom-= lineDescent-mMagnifierMaxDescent; |
|
428 } |
|
429 // Compensate for rounding error by adding +1 |
|
430 centerOfMagnification.setY(lineBottom-magnifierHeight/(2*mMagnifier->contentScale())+1); |
|
431 } |
|
432 |
|
433 mMagnifier->centerOnContent(centerOfMagnification); |
|
434 |
|
435 // -- Position magnifier -- |
|
436 |
|
437 // Convert cursorRect to HbSelectionControl's coordinate system |
|
438 QRectF rect = q->mapRectFromItem(HbAbstractEditPrivate::d_ptr(mEdit)->canvas,canvasCursorRect); |
|
439 |
|
440 QRectF boundingRect = mMagnifier->boundingRect(); |
|
441 boundingRect.moveCenter(rect.center()); |
|
442 |
|
443 const qreal KMagnifierBottomUpperBound = rect.top()-mMagnifierMarginFromLine+mTouchYOffsetFromMagnifierReferenceLine; |
|
444 const qreal KMagnifierBottomLowerBound = rect.bottom()-mMagnifierMarginFromLine+mTouchYOffsetFromMagnifierReferenceLine; |
|
445 |
|
446 qreal newMagnifierBottom = (mPressed == SelectionStartHandle?KMagnifierBottomUpperBound:KMagnifierBottomLowerBound); |
|
447 |
|
448 // -- Constrain vertical position -- |
|
449 |
|
450 // Constrain maximum distance of bottom of the magnifier from touch point |
|
451 newMagnifierBottom = qMax(newMagnifierBottom,mTouchPoint.y()-mMagnifierMaxYOffsetFromTouchPoint); |
|
452 |
|
453 // Constrain minimum distance of bottom of the magnifier from touch point |
|
454 newMagnifierBottom = qMin(newMagnifierBottom,mTouchPoint.y()-mMagnifierMinYOffsetFromTouchPoint); |
|
455 |
|
456 // Constrain the bottom of the magnifier to be within the feasible bounds |
|
457 newMagnifierBottom = qMin(qMax(newMagnifierBottom,KMagnifierBottomUpperBound),KMagnifierBottomLowerBound); |
|
458 |
|
459 boundingRect.moveBottom(newMagnifierBottom); |
|
460 boundingRect.moveTop(qMax(mVerticalScreenMargin,boundingRect.top())); |
|
461 |
|
462 // Readjust magnifier position if there is not enough space at the top of the screen |
|
463 if (mTouchPoint.y()-mMagnifierMinYOffsetFromTouchPoint < boundingRect.bottom()) { |
|
464 |
|
465 boundingRect.moveRight(mTouchPoint.x()-mMagnifierLeftRightMarginFromHandle); |
|
466 |
|
467 if(boundingRect.left() < 0) { |
|
468 boundingRect.moveLeft(mTouchPoint.x()+mMagnifierLeftRightMarginFromHandle); |
|
469 } |
|
470 } |
|
471 mMagnifier->setPos(boundingRect.topLeft()); |
|
472 #if HB_DEBUG_PAINT_INFO |
|
473 updateDebugPaintInfo(); |
|
474 #endif |
|
475 } |
|
476 |
|
477 } |
|
478 |
|
479 void HbSelectionControlPrivate::initMagnifier() |
|
480 { |
|
481 mMagnifier->setContentScale(MAGNIFIER_SCALE_FACTOR); |
|
482 mMagnifier->setZValue(100); |
|
483 mMagnifier->setMask(QLatin1String("qtg_fr_editor_magnifier_mask")); |
|
484 mMagnifier->setOverlay(QLatin1String("qtg_fr_editor_magnifier_overlay")); |
|
485 updateMagnifier(); |
|
486 } |
230 |
487 |
231 |
488 |
232 /* |
489 /* |
233 Reparents item to q if item's bounding rect intersects mEdit's viewPort rectangle or otherwise to |
490 Reparents item to q if item's bounding rect intersects mEdit's viewPort rectangle or otherwise to |
234 HbAbstractEditPrivate::d_ptr(d->mEdit)->canvas. |
491 HbAbstractEditPrivate::d_ptr(d->mEdit)->canvas. |
286 reparent(mSelectionEndHandle, newParent); |
543 reparent(mSelectionEndHandle, newParent); |
287 reparent(mSelectionEndTouchArea, newParent); |
544 reparent(mSelectionEndTouchArea, newParent); |
288 } |
545 } |
289 |
546 |
290 |
547 |
291 void HbSelectionControlPrivate::tapGestureFinished(const QPointF &pos) |
548 /* |
292 { |
549 Returns the constrained hit test point calculated from point. |
293 if (mEdit->contextMenuFlags().testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) { |
550 point has to be in HbSelectionControl's coordinate system. |
294 mEdit->showContextMenu(pos); |
551 The returned pos is also in HbSelectionControl's coordinate system. |
295 } |
552 */ |
296 } |
553 QPointF HbSelectionControlPrivate::constrainHitTestPoint(const QPointF& point) |
297 |
554 { |
298 void HbSelectionControlPrivate::panGestureStarted(HbPanGesture *gesture) |
555 Q_Q(HbSelectionControl); |
299 { |
556 |
300 Q_Q(HbSelectionControl); |
557 QRectF docRect = QRectF(q->mapFromItem(HbAbstractEditPrivate::d_ptr(mEdit)->canvas->parentItem(), |
301 |
558 HbAbstractEditPrivate::d_ptr(mEdit)->canvas->pos()), |
302 QPointF point = q->mapFromScene(gesture->sceneStartPos()); |
559 HbAbstractEditPrivate::d_ptr(mEdit)->doc->size()); |
303 mPressed = HbSelectionControl::DummyHandle; |
560 |
|
561 // Constrain hitTestPos within docRect with mLastCursorHeight/2 top/bottom margins. |
|
562 QPointF hitTestPos = QPointF(qMin(qMax(point.x(),docRect.left()),docRect.right()), |
|
563 qMin(qMax(point.y(),docRect.top()+mLastCursorHeight/2),docRect.bottom()-mLastCursorHeight/2)); |
|
564 |
|
565 #if HB_DEBUG_PAINT_INFO |
|
566 mDocRectDebug = docRect; |
|
567 #endif |
|
568 |
|
569 return hitTestPos; |
|
570 } |
|
571 |
|
572 |
|
573 /* |
|
574 Returns the handle whose touch area contains point. |
|
575 point has to be in HbSelectionControl's coordinate system. |
|
576 */ |
|
577 HbSelectionControlPrivate::HandleType HbSelectionControlPrivate::handleForPoint(const QPointF& point) { |
|
578 |
|
579 Q_Q(HbSelectionControl); |
|
580 |
|
581 HandleType pressed = DummyHandle; |
304 |
582 |
305 // Find out which handle is being moved |
583 // Find out which handle is being moved |
306 if (mSelectionStartTouchArea->contains(q->mapToItem(mSelectionStartTouchArea, point))) { |
584 if (mSelectionStartTouchArea->isVisible() && |
307 mPressed = HbSelectionControl::SelectionStartHandle; |
585 mSelectionStartTouchArea->contains(q->mapToItem(mSelectionStartTouchArea, point))) { |
|
586 pressed = SelectionStartHandle; |
308 } |
587 } |
309 if (mSelectionEndTouchArea->contains(q->mapToItem(mSelectionEndTouchArea, point))) { |
588 if (mSelectionEndTouchArea->contains(q->mapToItem(mSelectionEndTouchArea, point))) { |
310 bool useArea = true; |
589 bool useArea = true; |
311 if(mPressed != HbSelectionControl::DummyHandle) { |
590 if(pressed != DummyHandle) { |
312 |
591 |
313 // The press point was inside in both of the touch areas |
592 // The press point was inside in both of the touch areas |
314 // choose the touch area whose center is closer to the press point |
593 // choose the touch area whose center is closer to the press point |
315 QRectF rect = mSelectionStartTouchArea->boundingRect(); |
594 QRectF rect = mSelectionStartHandle->boundingRect(); |
316 rect.moveTopLeft(mSelectionStartTouchArea->pos()); |
595 rect.moveTopLeft(mSelectionStartHandle->pos()); |
317 QLineF lineEventPosSelStartCenter(point,rect.center()); |
596 QLineF lineEventPosSelStartCenter(point,rect.center()); |
318 |
597 |
319 rect = mSelectionEndTouchArea->boundingRect(); |
598 rect = mSelectionEndHandle->boundingRect(); |
320 rect.moveTopLeft(mSelectionEndTouchArea->pos()); |
599 rect.moveTopLeft(mSelectionEndHandle->pos()); |
321 QLineF lineEventPosSelEndCenter(point,rect.center()); |
600 QLineF lineEventPosSelEndCenter(point,rect.center()); |
322 |
601 |
323 if (lineEventPosSelStartCenter.length() < lineEventPosSelEndCenter.length()) { |
602 if (lineEventPosSelStartCenter.length() < lineEventPosSelEndCenter.length()) { |
324 useArea = false; |
603 useArea = false; |
325 } |
604 } |
326 } |
605 } |
327 if (useArea) { |
606 if (useArea) { |
328 mPressed = HbSelectionControl::SelectionEndHandle; |
607 pressed = SelectionEndHandle; |
329 } |
608 } |
330 } |
609 } |
331 |
610 |
332 if (mPressed == HbSelectionControl::DummyHandle) { |
611 return pressed; |
|
612 } |
|
613 |
|
614 void HbSelectionControlPrivate::gestureStarted(const QPointF &point) |
|
615 { |
|
616 mPressed = handleForPoint(point); |
|
617 mTouchPoint = point; |
|
618 |
|
619 if (mPressed == DummyHandle) { |
333 // Hit is outside touch areas, ignore |
620 // Hit is outside touch areas, ignore |
334 return; |
621 return; |
335 } |
622 } |
|
623 |
|
624 // Calculate touch offsets |
|
625 mHitTestPoint = mStartHandleHitTestPoint; |
|
626 qreal magnifierReferenceLine = mStartHandleMagnifierReferenceLine; |
|
627 if (mPressed == SelectionEndHandle) { |
|
628 mHitTestPoint = mEndHandleHitTestPoint; |
|
629 magnifierReferenceLine = mEndHandleMagnifierReferenceLine; |
|
630 } |
|
631 |
|
632 mTouchYOffsetFromMagnifierReferenceLine = point.y() - magnifierReferenceLine; |
|
633 mTouchOffsetFromHitTestPoint = mHitTestPoint - point; |
336 |
634 |
337 // Position cursor at the pressed selection handle |
635 // Position cursor at the pressed selection handle |
338 |
636 |
339 QTextCursor cursor = mEdit->textCursor(); |
637 QTextCursor cursor = mEdit->textCursor(); |
340 int selStartPos = qMin(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
638 int selStartPos = qMin(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
341 int selEndPos = qMax(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
639 int selEndPos = qMax(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
342 |
640 |
343 if (mPressed == HbSelectionControl::SelectionStartHandle) { |
641 if (mPressed == SelectionStartHandle) { |
344 cursor.setPosition(selEndPos); |
642 cursor.setPosition(selEndPos); |
345 cursor.setPosition(selStartPos, QTextCursor::KeepAnchor); |
643 cursor.setPosition(selStartPos, QTextCursor::KeepAnchor); |
346 } else { |
644 } else { |
347 cursor.setPosition(selStartPos); |
645 cursor.setPosition(selStartPos); |
348 cursor.setPosition(selEndPos, QTextCursor::KeepAnchor); |
646 cursor.setPosition(selEndPos, QTextCursor::KeepAnchor); |
349 } |
647 } |
350 mEdit->setTextCursor(cursor); |
648 mEdit->setTextCursor(cursor); |
351 |
649 } |
|
650 |
|
651 void HbSelectionControlPrivate::tapGestureStarted(HbTapGesture *gesture) |
|
652 { |
|
653 Q_Q(HbSelectionControl); |
|
654 |
|
655 mMagnifier->hideWithEffect(); |
|
656 if (!mDelayedTapTimer.isActive()) { |
|
657 mDelayedTapTimer.start(MAGNIFIER_OPEN_DELAY,q); |
|
658 } |
|
659 QPointF point = q->mapFromScene(gesture->sceneStartPos()); |
|
660 gestureStarted(point); |
|
661 } |
|
662 |
|
663 void HbSelectionControlPrivate::tapGestureFinished() |
|
664 { |
|
665 mDelayedTapTimer.stop(); |
|
666 if (!mIsPanActive) { |
|
667 mSelectionStartTouchArea->show(); |
|
668 mSelectionStartHandle->show(); |
|
669 mMagnifier->hideWithEffect(); |
|
670 } |
|
671 } |
|
672 |
|
673 void HbSelectionControlPrivate::delayedTapFinished() |
|
674 { |
|
675 Q_Q(HbSelectionControl); |
|
676 |
|
677 // Reset gesture override to have enable more responsive pan |
|
678 q->scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant()); |
|
679 |
|
680 if (mPressed == HbSelectionControlPrivate::SelectionEndHandle && mInteractionMode == HbSelectionControlPrivate::CursorPositioning) { |
|
681 mSelectionStartTouchArea->hide(); |
|
682 mSelectionStartHandle->hide(); |
|
683 } |
|
684 if (mMagnifierEnabled) { |
|
685 mMagnifier->showWithEffect(); |
|
686 q->updatePrimitives(); |
|
687 } |
|
688 } |
|
689 |
|
690 |
|
691 |
|
692 void HbSelectionControlPrivate::panGestureStarted(HbPanGesture *gesture) |
|
693 { |
|
694 Q_Q(HbSelectionControl); |
|
695 |
|
696 mIsPanActive = true; |
|
697 QPointF point = q->mapFromScene(gesture->sceneStartPos()); |
|
698 gestureStarted(point); |
|
699 if (mPressed == SelectionEndHandle && mInteractionMode == HbSelectionControlPrivate::CursorPositioning) { |
|
700 mSelectionStartTouchArea->hide(); |
|
701 mSelectionStartHandle->hide(); |
|
702 } |
352 } |
703 } |
353 |
704 |
354 |
705 |
355 void HbSelectionControlPrivate::panGestureFinished(HbPanGesture *gesture) |
706 void HbSelectionControlPrivate::panGestureFinished(HbPanGesture *gesture) |
356 { |
707 { |
371 cursor.setPosition(anchPos); |
722 cursor.setPosition(anchPos); |
372 cursor.setPosition(curPos, QTextCursor::KeepAnchor); |
723 cursor.setPosition(curPos, QTextCursor::KeepAnchor); |
373 mEdit->setTextCursor(cursor); |
724 mEdit->setTextCursor(cursor); |
374 } |
725 } |
375 |
726 |
376 mPressed = HbSelectionControl::DummyHandle; |
727 mSelectionStartTouchArea->show(); |
|
728 mSelectionStartHandle->show(); |
|
729 // This has to be set before updatePrimitives call |
|
730 mIsPanActive = false; |
377 q->updatePrimitives(); |
731 q->updatePrimitives(); |
|
732 mMagnifier->hideWithEffect(); |
|
733 |
|
734 // This has to be set at last |
|
735 mPressed = DummyHandle; |
|
736 } |
|
737 |
|
738 void HbSelectionControlPrivate::panGestureCanceled() |
|
739 { |
|
740 mMagnifier->hideWithEffect(); |
|
741 mIsPanActive = false; |
378 } |
742 } |
379 |
743 |
380 |
744 |
381 void HbSelectionControlPrivate::panGestureUpdated(HbPanGesture *gesture) |
745 void HbSelectionControlPrivate::panGestureUpdated(HbPanGesture *gesture) |
382 { |
746 { |
383 Q_Q(HbSelectionControl); |
747 Q_Q(HbSelectionControl); |
384 |
748 |
385 QRectF docRect = QRectF(mEdit->mapFromItem(HbAbstractEditPrivate::d_ptr(mEdit)->canvas->parentItem(), |
749 // Calculate new hittest point |
386 HbAbstractEditPrivate::d_ptr(mEdit)->canvas->pos()), |
750 QPointF point = q->mapFromScene(gesture->sceneStartPos() + gesture->sceneOffset()); |
387 HbAbstractEditPrivate::d_ptr(mEdit)->doc->size()); |
751 mTouchPoint = point; |
388 |
752 mHitTestPoint = (point + mTouchOffsetFromHitTestPoint); |
389 QPointF editPos = mEdit->mapFromScene(gesture->sceneStartPos() + gesture->sceneOffset()); |
753 mHitTestPoint = constrainHitTestPoint(mHitTestPoint); |
390 QPointF origEditPos = editPos; |
754 |
391 bool outsideCanvas = !docRect.contains(origEditPos); |
755 #if HB_DEBUG_PAINT_INFO |
392 |
756 updateDebugPaintInfo(); |
393 // Constrain editPos within docRect |
757 #endif |
394 editPos = QPointF(qMin(qMax(editPos.x(),docRect.left()),docRect.right()), |
|
395 qMin(qMax(editPos.y(),docRect.top()),docRect.bottom())); |
|
396 |
|
397 QRectF handleRect = mSelectionStartHandle->boundingRect(); |
|
398 |
|
399 handleRect.moveCenter(editPos); |
|
400 |
|
401 // Set hitTestPos based on which handle was grabbed |
|
402 QPointF hitTestPos = handleRect.center(); |
|
403 |
|
404 if (mPressed == HbSelectionControl::SelectionStartHandle) { |
|
405 hitTestPos.setY(handleRect.bottom()+1); |
|
406 } else { |
|
407 hitTestPos.setY(handleRect.top()-1); |
|
408 } |
|
409 |
|
410 // Override hitTestPos if origEditPos was outside the canvas |
|
411 if (outsideCanvas) { |
|
412 if (origEditPos.y() < docRect.top()) { |
|
413 hitTestPos.setY(handleRect.bottom()+1); |
|
414 } else if (docRect.bottom() < origEditPos.y()) { |
|
415 hitTestPos.setY(handleRect.top()-1); |
|
416 } |
|
417 } |
|
418 |
758 |
419 QTextCursor cursor; |
759 QTextCursor cursor; |
420 cursor = mEdit->textCursor(); |
760 cursor = mEdit->textCursor(); |
|
761 |
421 // Hit test for the center of current selection touch area |
762 // Hit test for the center of current selection touch area |
422 int hitPos = HbAbstractEditPrivate::d_ptr(mEdit)->hitTest(hitTestPos,Qt::FuzzyHit); |
763 int hitPos = HbAbstractEditPrivate::d_ptr(mEdit)->hitTest(q->mapToItem(mEdit,mHitTestPoint),Qt::FuzzyHit); |
423 |
764 |
424 // if no valid hit pos or empty selection return |
765 // if no valid hit pos or empty selection in read-only mode return |
425 if (hitPos == -1 || hitPos == cursor.anchor()) { |
766 if (hitPos == -1 || (mEdit->isReadOnly() && hitPos == cursor.anchor() && mInteractionMode == Selection)) { |
426 return; |
767 return; |
427 } |
768 } |
428 |
769 |
429 bool handlesMoved(false); |
770 bool isCursorMoved = false; |
430 if (hitPos != cursor.position()) { |
771 if (hitPos != cursor.position()) { |
431 handlesMoved = true; |
772 isCursorMoved = true; |
432 } |
773 } |
433 cursor.setPosition(hitPos, QTextCursor::KeepAnchor); |
774 |
434 if (handlesMoved) { |
775 cursor.setPosition(hitPos, ((mInteractionMode==Selection||mPressed == SelectionStartHandle) |
|
776 ?QTextCursor::KeepAnchor:QTextCursor::MoveAnchor)); |
|
777 |
|
778 if (isCursorMoved) { |
435 if (mEdit) { |
779 if (mEdit) { |
436 HbWidgetFeedback::triggered(mEdit, Hb::InstantDraggedOver); |
780 HbWidgetFeedback::triggered(mEdit, Hb::InstantDraggedOver); |
437 } |
781 } |
438 // Restart timer every time when a selection handle moved |
782 if (mInteractionMode==Selection) { |
439 mWordSnapTimer.start(SNAP_DELAY, q); |
783 // Restart timer every time when a selection handle moved |
|
784 mWordSnapTimer.start(SNAP_DELAY, q); |
|
785 } |
440 mEdit->setTextCursor(cursor); |
786 mEdit->setTextCursor(cursor); |
441 } |
787 } |
442 |
788 |
443 // Ensure that the hitPos is visible |
789 // Ensure that the hitPos is visible |
444 HbAbstractEditPrivate::d_ptr(mEdit)->ensurePositionVisible(hitPos); |
790 HbAbstractEditPrivate::d_ptr(mEdit)->ensurePositionVisible(hitPos); |
|
791 if (mMagnifierEnabled) { |
|
792 mMagnifier->showWithEffect(); |
|
793 } |
445 q->updatePrimitives(); |
794 q->updatePrimitives(); |
|
795 |
446 } |
796 } |
447 |
797 |
448 void HbSelectionControlPrivate::show() { |
798 void HbSelectionControlPrivate::show() { |
449 Q_Q(HbSelectionControl); |
799 Q_Q(HbSelectionControl); |
450 |
800 |
583 { |
981 { |
584 Q_D(HbSelectionControl); |
982 Q_D(HbSelectionControl); |
585 |
983 |
586 if (event->timerId() == d->mWordSnapTimer.timerId()) { |
984 if (event->timerId() == d->mWordSnapTimer.timerId()) { |
587 d->mWordSnapTimer.stop(); |
985 d->mWordSnapTimer.stop(); |
|
986 } else if (event->timerId() == d->mDelayedTapTimer.timerId()) { |
|
987 d->mDelayedTapTimer.stop(); |
|
988 d->delayedTapFinished(); |
588 } |
989 } |
589 } |
990 } |
590 |
991 |
591 void HbSelectionControl::polish( HbStyleParameters& params ) |
992 void HbSelectionControl::polish( HbStyleParameters& params ) |
592 { |
993 { |
593 Q_D(HbSelectionControl); |
994 Q_D(HbSelectionControl); |
594 |
995 |
595 HbWidget::polish(params); |
996 if (isVisible()) { |
596 QSizeF size = d->mSelectionStartTouchArea->preferredSize(); |
997 |
597 d->mSelectionStartTouchArea->resize(size); |
998 const QLatin1String KHandleMarginFromLine("handle-margin-from-line"); |
598 d->mSelectionEndTouchArea->resize(size); |
999 const QLatin1String KMagnifierMarginFromLine("magnifier-margin-from-line"); |
599 updatePrimitives(); |
1000 const QLatin1String KMagnifierLeftRightMarginFromHandle("magnifier-left-right-margin-from-handle"); |
|
1001 const QLatin1String KMagnifierMaxDescent("magnifier-max-descent"); |
|
1002 |
|
1003 params.addParameter(KHandleMarginFromLine); |
|
1004 params.addParameter(KMagnifierMarginFromLine); |
|
1005 params.addParameter(KMagnifierLeftRightMarginFromHandle); |
|
1006 params.addParameter(KMagnifierMaxDescent); |
|
1007 |
|
1008 HbWidget::polish(params); |
|
1009 |
|
1010 // Set size of handles |
|
1011 QSizeF size = d->mSelectionStartHandle->preferredSize(); |
|
1012 d->mSelectionStartHandle->setSize(size); |
|
1013 d->mSelectionEndHandle->setSize(size); |
|
1014 |
|
1015 // Set max y offset for hit test point |
|
1016 // TODO: consider setting this value from css |
|
1017 d->mMaxHitTestPointOffsetYFromLine = size.height(); |
|
1018 |
|
1019 // Set size of touch areas |
|
1020 size = d->mSelectionEndTouchArea->preferredSize(); |
|
1021 d->mSelectionEndTouchArea->resize(size); |
|
1022 |
|
1023 |
|
1024 // Increase the height of the touch area of the start selection handle |
|
1025 size.setHeight(size.height()*2-d->mSelectionStartHandle->size().height()); |
|
1026 d->mSelectionStartTouchArea->resize(size); |
|
1027 |
|
1028 |
|
1029 |
|
1030 // Set size of magnifier |
|
1031 d->mMagnifier->resize(d->mMagnifier->preferredSize()); |
|
1032 |
|
1033 if (params.value(KHandleMarginFromLine).isValid()) { |
|
1034 d->mHandleMarginFromLine = params.value(KHandleMarginFromLine).toReal(); |
|
1035 } |
|
1036 |
|
1037 if (params.value(KMagnifierMarginFromLine).isValid()) { |
|
1038 d->mMagnifierMarginFromLine = params.value(KMagnifierMarginFromLine).toReal(); |
|
1039 } |
|
1040 if (params.value(KMagnifierLeftRightMarginFromHandle).isValid()) { |
|
1041 d->mMagnifierLeftRightMarginFromHandle = params.value(KMagnifierLeftRightMarginFromHandle).toReal(); |
|
1042 } |
|
1043 |
|
1044 if (params.value(KMagnifierMaxDescent).isValid()) { |
|
1045 d->mMagnifierMaxDescent = params.value(KMagnifierMaxDescent).toReal(); |
|
1046 } |
|
1047 |
|
1048 // Set the min/max magnifier touch offsets |
|
1049 // TODO: consider setting this value from css |
|
1050 d->mMagnifierMaxYOffsetFromTouchPoint = d->mMagnifierMarginFromLine*2; |
|
1051 d->mMagnifierMinYOffsetFromTouchPoint = d->mMagnifierMarginFromLine/2; |
|
1052 |
|
1053 updatePrimitives(); |
|
1054 } else { |
|
1055 HbWidget::polish(params); |
|
1056 } |
600 } |
1057 } |
601 |
1058 |
602 QVariant HbSelectionControl::itemChange(GraphicsItemChange change, const QVariant &value) |
1059 QVariant HbSelectionControl::itemChange(GraphicsItemChange change, const QVariant &value) |
603 { |
1060 { |
604 if (change == QGraphicsItem::ItemPositionChange) { |
1061 if (change == QGraphicsItem::ItemPositionChange) { |
650 d->panGestureFinished(pan); |
1107 d->panGestureFinished(pan); |
651 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
1108 HbWidgetFeedback::triggered(this, Hb::InstantReleased); |
652 } |
1109 } |
653 break; |
1110 break; |
654 case Qt::GestureCanceled: |
1111 case Qt::GestureCanceled: |
|
1112 if (d->mEdit) { |
|
1113 d->panGestureCanceled(); |
|
1114 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantReleased); |
|
1115 } |
655 break; |
1116 break; |
656 default: |
1117 default: |
657 break; |
1118 break; |
658 } |
1119 } |
659 } |
1120 } |
660 } |
1121 } |
661 |
1122 |
|
1123 bool HbSelectionControl::eventFilter(QObject * watched, QEvent *event) |
|
1124 { |
|
1125 Q_UNUSED(watched) |
|
1126 |
|
1127 // Filter gesture events and delegate to gestureEvent() |
|
1128 if (event->type() == QEvent::Gesture || event->type() == QEvent::GestureOverride) { |
|
1129 gestureEvent(static_cast<QGestureEvent*>(event)); |
|
1130 return true; |
|
1131 } |
|
1132 return false; |
|
1133 } |
|
1134 |
|
1135 |
662 bool HbSelectionControl::event(QEvent *event) |
1136 bool HbSelectionControl::event(QEvent *event) |
663 { |
1137 { |
664 Q_D(HbSelectionControl); |
1138 Q_D(HbSelectionControl); |
665 |
1139 |
666 if (event->type() == HbEvent::DeviceProfileChanged && d->mEdit) { |
1140 if (event->type() == HbEvent::DeviceProfileChanged && d->mEdit) { |
667 HbDeviceProfileChangedEvent* dpEvent = static_cast<HbDeviceProfileChangedEvent*>(event); |
1141 HbDeviceProfileChangedEvent* dpEvent = static_cast<HbDeviceProfileChangedEvent*>(event); |
668 if ( dpEvent->profile().alternateProfileName() == dpEvent->oldProfile().name() ) { |
1142 if ( dpEvent->profile().alternateProfileName() == dpEvent->oldProfile().name() ) { |
|
1143 d->initMagnifier(); |
669 updatePrimitives(); |
1144 updatePrimitives(); |
670 } |
1145 } |
671 } |
1146 } |
672 return HbWidget::event(event); |
1147 return HbWidget::event(event); |
673 } |
1148 } |
674 |
1149 |
|
1150 |
|
1151 void HbSelectionControl::setMagnifierEnabled(bool enable) |
|
1152 { |
|
1153 Q_D(HbSelectionControl); |
|
1154 d->mMagnifierEnabled = enable; |
|
1155 } |
|
1156 |
|
1157 bool HbSelectionControl::isMagnifierEnabled() const |
|
1158 { |
|
1159 Q_D(const HbSelectionControl); |
|
1160 return d->mMagnifierEnabled; |
|
1161 } |
|
1162 |
|
1163 void HbSelectionControl::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
1164 { |
|
1165 Q_UNUSED(widget) |
|
1166 Q_UNUSED(option) |
|
1167 Q_UNUSED(painter) |
|
1168 |
|
1169 #if HB_DEBUG_PAINT_INFO |
|
1170 Q_D(HbSelectionControl); |
|
1171 painter->save(); |
|
1172 |
|
1173 // draw mHitTestPoint |
|
1174 painter->setPen(Qt::yellow); |
|
1175 painter->setBrush(Qt::yellow); |
|
1176 painter->drawEllipse(d->mHitTestPoint, 3,3); |
|
1177 |
|
1178 // draw mDocRectDebug |
|
1179 painter->setBrush(Qt::NoBrush); |
|
1180 painter->drawRect(d->mDocRectDebug); |
|
1181 |
|
1182 // draw line representing mMagnifierMaxYOffsetFromTouchPoint |
|
1183 painter->setPen(Qt::red); |
|
1184 qreal magnifierMaxYOffsetLine = d->mTouchPoint.y()-d->mMagnifierMaxYOffsetFromTouchPoint; |
|
1185 painter->drawLine(QPointF(0,magnifierMaxYOffsetLine),QPointF(500,magnifierMaxYOffsetLine)); |
|
1186 |
|
1187 // draw line representing mMagnifierMinYOffsetFromTouchPoint |
|
1188 painter->setPen(Qt::green); |
|
1189 qreal magnifierMinYOffsetLine = d->mTouchPoint.y()-d->mMagnifierMinYOffsetFromTouchPoint; |
|
1190 painter->drawLine(QPointF(0,magnifierMinYOffsetLine),QPointF(500,magnifierMinYOffsetLine)); |
|
1191 |
|
1192 // draw line representing magnifierStartYOffsetLine |
|
1193 painter->setPen(Qt::black); |
|
1194 qreal magnifierStartYOffsetLine = d->mStartHandleMagnifierReferenceLine - d->mMagnifierMarginFromLine; |
|
1195 painter->drawLine(QPointF(0,magnifierStartYOffsetLine),QPointF(500,magnifierStartYOffsetLine)); |
|
1196 |
|
1197 // draw line representing magnifierStartYOffsetLine |
|
1198 painter->setPen(Qt::magenta); |
|
1199 qreal magnifierEndYOffsetLine = d->mEndHandleMagnifierReferenceLine - d->mMagnifierMarginFromLine; |
|
1200 painter->drawLine(QPointF(0,magnifierEndYOffsetLine),QPointF(500,magnifierEndYOffsetLine)); |
|
1201 |
|
1202 |
|
1203 painter->drawRect(boundingRect()); |
|
1204 |
|
1205 painter->restore(); |
|
1206 #endif |
|
1207 |
|
1208 } |
|
1209 |
|
1210 |
675 void HbSelectionControl::updatePrimitives() |
1211 void HbSelectionControl::updatePrimitives() |
676 { |
1212 { |
677 Q_D(HbSelectionControl); |
1213 Q_D(HbSelectionControl); |
678 |
1214 |
679 if (isVisible() && d->polished && d->mEdit) { |
1215 if (isVisible() && d->polished && d->mEdit) { |
680 if (d->mEdit->textCursor().hasSelection() ) { |
1216 |
681 |
1217 const bool hasSelection = d->mEdit->textCursor().hasSelection(); |
682 int selStartPos = qMin(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
1218 |
683 int selEndPos = qMax(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
1219 // The interaction mode can be change only when there is no pan in progress |
684 |
1220 if (!d->mIsPanActive) { |
685 d->updateHandle(selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea,HbStyle::P_SelectionControl_selectionstart); |
1221 d->mInteractionMode = (hasSelection?HbSelectionControlPrivate::Selection: |
686 d->updateHandle(selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea,HbStyle::P_SelectionControl_selectionend); |
1222 HbSelectionControlPrivate::CursorPositioning); |
687 } |
1223 } |
688 else { |
1224 |
689 hide(); |
1225 const int cursorPos = d->mEdit->textCursor().position(); |
690 } |
1226 int selStartPos = cursorPos; |
|
1227 int selEndPos = cursorPos; |
|
1228 d->mSelectionEndHandle->setIconName(QLatin1String("qtg_graf_editor_handle_finetune")); |
|
1229 |
|
1230 if (hasSelection) { |
|
1231 selStartPos = qMin(d->mEdit->textCursor().anchor(),cursorPos); |
|
1232 selEndPos = qMax(d->mEdit->textCursor().anchor(),cursorPos); |
|
1233 d->mSelectionEndHandle->setIconName(QLatin1String("qtg_graf_editor_handle_end")); |
|
1234 } |
|
1235 |
|
1236 d->updateHandle(cursorPos,selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea); |
|
1237 d->updateHandle(cursorPos,selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea); |
|
1238 d->updateMagnifier(); |
691 } |
1239 } |
692 } |
1240 } |
693 #include "moc_hbselectioncontrol_p.cpp" |
1241 #include "moc_hbselectioncontrol_p.cpp" |
|
1242 |