00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "input.h"
00023 #include "input.moc"
00024
00025 #include <QPainter>
00026 #include <QStyleOptionGraphicsItem>
00027 #include <QGraphicsSceneMouseEvent>
00028 #include <QCursor>
00029
00030 #include "textfield.h"
00031
00032 Input::Input(Karamba* k, int x, int y, int w, int h)
00033 : Meter(k, x, y, w, h),
00034 m_selectionColor(128, 128, 128),
00035 m_hscroll(0),
00036 m_cursorPos(0),
00037 m_cursorVisible(true),
00038 m_mouseMoved(false),
00039 m_selStart(-1),
00040 m_selLength(0)
00041 {
00042 setFlags(QGraphicsItem::ItemIsFocusable);
00043
00044 setCursor(QCursor(Qt::IBeamCursor));
00045
00046 connect(&m_cursorTimer, SIGNAL(timeout()), (QObject*)this, SLOT(blinkCursor()));
00047 m_cursorTimer.start(1000);
00048 }
00049
00050 Input::~Input()
00051 {}
00052
00053
00054
00055
00056
00057 void Input::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
00058 QWidget *widget)
00059 {
00060 Q_UNUSED(option);
00061 Q_UNUSED(widget);
00062
00063 painter->setPen(m_fgColor);
00064 QBrush oldBrush = painter->brush();
00065 painter->setBrush(m_bgColor);
00066 painter->drawRect(boundingRect());
00067 painter->setBrush(oldBrush);
00068
00069 QTextLine line = m_textLayout.lineAt(0);
00070
00071 int widthUsed = qRound(line.naturalTextWidth()) + 1 + 4;
00072
00073 QFontMetrics fm(m_font);
00074 QRectF innerRect(boundingRect().x() + 2, boundingRect().y(),
00075 boundingRect().width() - 4, boundingRect().height());
00076 painter->setClipRect(innerRect);
00077
00078 QPointF topLeft = innerRect.topLeft();
00079
00080 double curPos = line.cursorToX(m_cursorPos);
00081 if (4 + widthUsed <= innerRect.width()) {
00082 m_hscroll = 0;
00083 } else if (curPos - m_hscroll >= innerRect.width()) {
00084 m_hscroll = curPos - innerRect.width() + 1;
00085 } else if (curPos - m_hscroll < 0) {
00086 m_hscroll = curPos;
00087 } else if (widthUsed - m_hscroll < innerRect.width()) {
00088 m_hscroll = widthUsed - innerRect.width() + 1;
00089 }
00090 topLeft.rx() -= m_hscroll;
00091 topLeft.ry() += (boundingRect().height() - line.height()) / 2;
00092
00093 painter->setPen(m_fontColor);
00094 m_textLayout.draw(painter, topLeft, m_selection, innerRect);
00095
00096 if (hasFocus() && m_cursorVisible)
00097 m_textLayout.drawCursor(painter, topLeft, m_cursorPos);
00098 }
00099
00100 void Input::mouseEvent(QEvent *e)
00101 {
00102 QPointF pos;
00103 if (QGraphicsSceneMouseEvent *event = dynamic_cast<QGraphicsSceneMouseEvent*>(e)) {
00104 pos = event->pos();
00105 } else if (QGraphicsSceneWheelEvent *event = dynamic_cast<QGraphicsSceneWheelEvent*>(e)) {
00106 pos = event->pos();
00107 }
00108
00109 QTextLine line = m_textLayout.lineAt(0);
00110
00111 QPoint mappedPos = mapFromParent(pos).toPoint();
00112 m_cursorPos = line.xToCursor(mappedPos.x() - 2 + m_hscroll);
00113 m_cursorVisible = true;
00114
00115 m_selStart = m_cursorPos;
00116
00117 update();
00118 }
00119
00120 void Input::mouseEventRelease(QGraphicsSceneMouseEvent *e)
00121 {
00122 if (m_mouseMoved) {
00123 QTextLine line = m_textLayout.lineAt(0);
00124 QPoint mappedPos = mapFromParent(e->pos()).toPoint();
00125 int selEnd = line.xToCursor(mappedPos.x() - 2 + m_hscroll);
00126 if (m_selStart > selEnd) {
00127 m_selLength = m_selStart - selEnd;
00128 m_selStart = selEnd;
00129 m_cursorPos = selEnd;
00130 } else {
00131 m_selLength = selEnd - m_selStart;
00132 m_cursorPos = m_selStart + m_selLength;
00133 }
00134 m_mouseMoved = false;
00135
00136 m_selection.clear();
00137 QTextLayout::FormatRange selection;
00138 selection.format.setBackground(m_selectionColor);
00139 selection.format.setForeground(m_selectedTextColor);
00140 selection.start = m_selStart;
00141 selection.length = m_selLength;
00142 m_selection << selection;
00143
00144 update();
00145 } else {
00146 m_selStart = -1;
00147 m_selLength = 0;
00148 }
00149 }
00150
00151 void Input::mouseEventMove(QGraphicsSceneHoverEvent *e)
00152 {
00153 Q_UNUSED(e);
00154 m_mouseMoved = true;
00155 }
00156
00157 void Input::focusOutEvent(QFocusEvent *event)
00158 {
00159 Q_UNUSED(event);
00160
00161 m_cursorTimer.stop();
00162 update();
00163 }
00164
00165 void Input::blinkCursor()
00166 {
00167 m_cursorVisible = !m_cursorVisible;
00168 update();
00169 }
00170
00171 void Input::keyPress(QKeyEvent *event)
00172 {
00173 bool append = true;
00174 bool newSelection = false;
00175 bool clearSelection = false;
00176
00177 switch (event->key()) {
00178 case Qt::Key_Backspace:
00179 if (m_selLength == 0) {
00180 if (m_cursorPos > 0) {
00181 m_text.remove(m_cursorPos - 1, 1);
00182 m_cursorPos--;
00183 }
00184 } else {
00185 m_text.remove(m_selStart, m_selLength);
00186 m_cursorPos = m_selStart;
00187 m_selStart = -1;
00188 m_selLength = 0;
00189 m_selection.clear();
00190 }
00191 append = false;
00192 break;
00193
00194 case Qt::Key_Delete:
00195 if (m_selLength == 0) {
00196 if (m_cursorPos >= 0) {
00197 m_text.remove(m_cursorPos, 1);
00198 }
00199 } else {
00200 m_text.remove(m_selStart, m_selLength);
00201 m_cursorPos = m_selStart;
00202 m_selStart = -1;
00203 m_selLength = 0;
00204 m_selection.clear();
00205 }
00206 append = false;
00207 break;
00208
00209 case Qt::Key_Left:
00210 m_cursorPos--;
00211 if (event->modifiers() == Qt::ShiftModifier) {
00212 if (m_cursorPos != -1) {
00213 if (m_selLength > 0) {
00214 if (m_cursorPos + 1 == m_selStart) {
00215 m_selStart--;
00216 m_selLength += 1;
00217 } else {
00218 m_selLength -= 1;
00219 }
00220 } else {
00221 m_selStart = m_cursorPos;
00222 m_selLength += 1;
00223 }
00224 newSelection = true;
00225 }
00226 } else {
00227 clearSelection = true;
00228 }
00229 append = false;
00230 break;
00231
00232 case Qt::Key_Right:
00233 m_cursorPos++;
00234 if (event->modifiers() == Qt::ShiftModifier) {
00235 if (m_cursorPos != m_text.length()+1) {
00236 if (m_selLength > 0) {
00237 if (m_cursorPos - 1 == m_selStart) {
00238 m_selStart++;
00239 m_selLength -= 1;
00240 } else {
00241 m_selLength += 1;
00242 }
00243 } else {
00244 m_selStart = m_cursorPos-1;
00245 m_selLength += 1;
00246 }
00247 newSelection = true;
00248 }
00249 } else {
00250 clearSelection = true;
00251 }
00252 append = false;
00253 break;
00254
00255 case Qt::Key_Home:
00256 {
00257 int oldCursorPos = m_cursorPos;
00258 m_cursorPos = 0;
00259 if (event->modifiers() == Qt::ShiftModifier) {
00260 m_selStart = 0;
00261 m_selLength = oldCursorPos;
00262 newSelection = true;
00263 }
00264 append = false;
00265 }
00266 break;
00267
00268 case Qt::Key_End:
00269 {
00270 int oldCursorPos = m_cursorPos;
00271 m_cursorPos = m_text.length();
00272 if (event->modifiers() == Qt::ShiftModifier) {
00273 m_selStart = oldCursorPos;
00274 m_selLength = m_cursorPos - oldCursorPos;
00275 newSelection = true;
00276 }
00277 append = false;
00278 }
00279 break;
00280
00281 case Qt::Key_Enter:
00282 case Qt::Key_Return:
00283 clearSelection = true;
00284 append = false;
00285 break;
00286 }
00287
00288 if (append) {
00289 if (m_selLength == 0) {
00290 m_text.insert(m_cursorPos, event->text());
00291 m_cursorPos += event->text().length();
00292 } else {
00293 if (event->text().length() > 0) {
00294 m_text.remove(m_selStart, m_selLength);
00295 m_text.insert(m_selStart, event->text());
00296 m_cursorPos = m_selStart + event->text().length();
00297 clearSelection = true;
00298 }
00299 }
00300 }
00301
00302 if (clearSelection) {
00303 m_selection.clear();
00304 m_selStart = -1;
00305 m_selLength = 0;
00306 }
00307
00308 if (newSelection) {
00309 m_selection.clear();
00310 QTextLayout::FormatRange selection;
00311 selection.format.setBackground(m_selectionColor);
00312 selection.format.setForeground(m_selectedTextColor);
00313 selection.start = m_selStart;
00314 selection.length = m_selLength;
00315 m_selection << selection;
00316 }
00317
00318 if (m_cursorPos < 0)
00319 m_cursorPos = 0;
00320 if (m_cursorPos > m_text.length())
00321 m_cursorPos = m_text.length();
00322
00323 m_cursorVisible = true;
00324
00325 layoutText();
00326 }
00327
00328
00329 void Input::setValue(const QString &text)
00330 {
00331 m_text = text;
00332
00333 layoutText();
00334 }
00335
00336 QString Input::getStringValue() const
00337 {
00338 return m_text;
00339 }
00340
00341 void Input::setBGColor(QColor c)
00342 {
00343 m_bgColor = c;
00344 update();
00345 }
00346
00347 void Input::setColor(QColor c)
00348 {
00349 m_fgColor = c;
00350 update();
00351 }
00352
00353 QColor Input::getBGColor() const
00354 {
00355 return m_bgColor;
00356 }
00357
00358 QColor Input::getColor() const
00359 {
00360 return m_fgColor;
00361 }
00362
00363 void Input::hide()
00364 {
00365 Meter::hide();
00366 }
00367
00368 void Input::show()
00369 {
00370 Meter::show();
00371 }
00372
00373 void Input::setSize(int ix, int iy, int iw, int ih)
00374 {
00375 Meter::setSize(ix, iy, iw, ih);
00376 }
00377
00378 void Input::setX(int ix)
00379 {
00380 Meter::setX(ix);
00381 }
00382
00383 void Input::setY(int iy)
00384 {
00385 Meter::setY(iy);
00386 }
00387
00388 void Input::setWidth(int iw)
00389 {
00390 Meter::setWidth(iw);
00391 }
00392
00393 void Input::setHeight(int ih)
00394 {
00395 Meter::setHeight(ih);
00396 }
00397
00398 void Input::setFont(const QString &f)
00399 {
00400 m_font.setFamily(f);
00401
00402 layoutText();
00403 }
00404
00405 QString Input::getFont() const
00406 {
00407 return m_font.family();
00408 }
00409
00410 void Input::setFontColor(QColor fontColor)
00411 {
00412 m_fontColor = fontColor;
00413 update();
00414 }
00415
00416 QColor Input::getFontColor() const
00417 {
00418 return m_fontColor;
00419 }
00420
00421 void Input::setSelectionColor(QColor selectionColor)
00422 {
00423 m_selectionColor = selectionColor;
00424 update();
00425 }
00426
00427 QColor Input::getSelectionColor() const
00428 {
00429 return m_selectionColor;
00430 }
00431
00432 void Input::setSelectedTextColor(QColor selectedTextColor)
00433 {
00434 m_selectedTextColor = selectedTextColor;
00435 }
00436
00437 QColor Input::getSelectedTextColor() const
00438 {
00439 return m_selectedTextColor;
00440 }
00441
00442 void Input::setFontSize(int size)
00443 {
00444 m_font.setPixelSize(size);
00445
00446 layoutText();
00447 }
00448
00449 int Input::getFontSize() const
00450 {
00451 return m_font.pixelSize();
00452 }
00453
00454 void Input::setTextProps(TextField* t)
00455 {
00456 if (t) {
00457 setFontSize(t->getFontSize());
00458 setFont(t->getFont());
00459 setColor(t->getColor());
00460 setBGColor(t->getBGColor());
00461 }
00462
00463 layoutText();
00464 }
00465
00466 void Input::setInputFocus()
00467 {
00468 setFocus();
00469 update();
00470 }
00471
00472 void Input::clearInputFocus()
00473 {
00474 clearFocus();
00475 update();
00476 }
00477
00478 void Input::layoutText()
00479 {
00480 m_textLayout.setText(m_text);
00481 m_textLayout.setFont(m_font);
00482
00483 m_textLayout.beginLayout();
00484 QTextLine line = m_textLayout.createLine();
00485 line.setPosition(QPointF(0, 0));
00486 m_textLayout.endLayout();
00487
00488 update();
00489 }
00490
00491 int Input::getTextWidth() const
00492 {
00493 QTextLine line = m_textLayout.lineAt(0);
00494 if (line.isValid()) {
00495 return static_cast<int>(line.naturalTextWidth());
00496 }
00497 return -1;
00498 }
00499
00500 void Input::setSelection(int start, int length)
00501 {
00502 m_selStart = start;
00503 m_selLength = length;
00504
00505 m_selection.clear();
00506 QTextLayout::FormatRange selection;
00507 selection.format.setBackground(m_selectionColor);
00508 selection.format.setForeground(m_selectedTextColor);
00509 selection.start = m_selStart;
00510 selection.length = m_selLength;
00511 m_selection << selection;
00512
00513 update();
00514 }
00515
00516 void Input::clearSelection()
00517 {
00518 setSelection(-1, 0);
00519 }
00520
00521 QTextLayout::FormatRange Input::getSelection() const
00522 {
00523 QTextLayout::FormatRange selection;
00524 selection.start = m_selStart;
00525 selection.length = m_selLength;
00526
00527 return selection;
00528 }