| |
| |
| #include "toonzqt/dvtextedit.h" |
| #include "toonzqt/gutil.h" |
| |
| #include <QLabel> |
| #include <QLineEdit> |
| #include <QVBoxLayout> |
| #include <QPainter> |
| #include <QToolBar> |
| #include <QFontComboBox> |
| #include <QAction> |
| #include <QMouseEvent> |
| #include <QTextCursor> |
| #include <QColorDialog> |
| #include <QComboBox> |
| #include <QFontDatabase> |
| |
| #include "toonzqt/colorfield.h" |
| |
| namespace { |
| |
| |
| |
| qreal distanceBetweenPointandRect(const QRect &rect, const QPoint &point) { |
| if (rect.contains(point)) return 0; |
| |
| qreal topLeftDistance = |
| sqrt(pow((double)(point.x() - rect.topLeft().x()), 2) + |
| pow((double)(point.y() - rect.topLeft().y()), 2)); |
| qreal topRightDistance = |
| sqrt(pow((double)(point.x() - rect.topRight().x()), 2) + |
| pow((double)(point.y() - rect.topRight().y()), 2)); |
| qreal bottomLeftDistance = |
| sqrt(pow((double)(point.x() - rect.bottomLeft().x()), 2) + |
| pow((double)(point.y() - rect.bottomLeft().y()), 2)); |
| qreal bottomRightDistance = |
| sqrt(pow((double)(point.x() - rect.bottomRight().x()), 2) + |
| pow((double)(point.y() - rect.bottomRight().y()), 2)); |
| |
| qreal topMax = qMin(topLeftDistance, topRightDistance); |
| qreal bottomMax = qMin(bottomLeftDistance, bottomRightDistance); |
| |
| return qMin(topMax, bottomMax); |
| } |
| } |
| |
| using namespace DVGui; |
| |
| |
| |
| |
| |
| DvMiniToolBar::DvMiniToolBar(QWidget *parent) |
| : QFrame(parent), m_dragPos(0, 0) { |
| setObjectName("DvMiniToolBar"); |
| setStyleSheet("#DvMiniToolBar {border: 1px solid black;}"); |
| setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); |
| } |
| |
| |
| |
| DvMiniToolBar::~DvMiniToolBar() {} |
| |
| |
| |
| void DvMiniToolBar::mousePressEvent(QMouseEvent *e) { |
| if (e->button() == Qt::LeftButton) |
| m_dragPos = e->globalPos() - frameGeometry().topLeft(); |
| |
| QWidget::mousePressEvent(e); |
| } |
| |
| |
| |
| void DvMiniToolBar::mouseMoveEvent(QMouseEvent *e) { |
| if (e->buttons() == Qt::LeftButton) move(e->globalPos() - m_dragPos); |
| |
| QWidget::mouseMoveEvent(e); |
| } |
| |
| |
| |
| |
| |
| DvTextEditButton::DvTextEditButton(QWidget *parent) : QWidget(parent) { |
| setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); |
| setFixedSize(16, 16); |
| } |
| |
| |
| |
| DvTextEditButton::~DvTextEditButton() {} |
| |
| |
| |
| void DvTextEditButton::paintEvent(QPaintEvent *) { |
| QPainter p(this); |
| static QPixmap pixmap(":Resources/text_edit_button.png"); |
| p.drawPixmap(0, 0, width(), height(), pixmap); |
| } |
| |
| |
| |
| void DvTextEditButton::mousePressEvent(QMouseEvent *) { |
| emit clicked(); |
| hide(); |
| } |
| |
| |
| |
| |
| |
| DvTextEdit::DvTextEdit(QWidget *parent) |
| : QTextEdit(parent), m_miniToolBarEnabled(true), m_mousePos(0, 0) { |
| setMouseTracking(true); |
| createActions(); |
| createMiniToolBar(); |
| |
| m_button = new DvTextEditButton(0); |
| m_button->hide(); |
| connect(m_button, SIGNAL(clicked()), this, SLOT(onShowMiniToolBarClicked())); |
| |
| fontChanged(font()); |
| setTextColor(TPixel32::Black, false); |
| alignmentChanged(alignment()); |
| |
| connect(this, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)), this, |
| SLOT(onCurrentCharFormatChanged(const QTextCharFormat &))); |
| |
| connect(this, SIGNAL(cursorPositionChanged()), this, |
| SLOT(onCursorPositionChanged())); |
| |
| connect(this, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); |
| } |
| |
| |
| void DvTextEdit::changeFont(const QFont &f) { |
| QTextCharFormat fmt = currentCharFormat(); |
| |
| fmt.setFont(f); |
| |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| DvTextEdit::~DvTextEdit() {} |
| |
| |
| |
| void DvTextEdit::createActions() { |
| m_boldAction = new QAction(createQIconOnOffPNG("bold"), tr("Bold"), this); |
| m_boldAction->setCheckable(true); |
| connect(m_boldAction, SIGNAL(triggered()), this, SLOT(setTextBold())); |
| |
| m_italicAction = |
| new QAction(createQIconOnOffPNG("italic"), tr("Italic"), this); |
| m_italicAction->setCheckable(true); |
| connect(m_italicAction, SIGNAL(triggered()), this, SLOT(setTextItalic())); |
| |
| m_underlineAction = |
| new QAction(createQIconOnOffPNG("underline"), tr("Underline"), this); |
| m_underlineAction->setCheckable(true); |
| connect(m_underlineAction, SIGNAL(triggered()), this, |
| SLOT(setTextUnderline())); |
| |
| m_colorField = new DVGui::ColorField(this, true, TPixel32(), 30); |
| m_colorField->hideChannelsFields(true); |
| connect(m_colorField, SIGNAL(colorChanged(const TPixel32 &, bool)), this, |
| SLOT(setTextColor(const TPixel32 &, bool))); |
| |
| m_alignActionGroup = new QActionGroup(this); |
| connect(m_alignActionGroup, SIGNAL(triggered(QAction *)), this, |
| SLOT(setTextAlign(QAction *))); |
| |
| m_alignLeftAction = new QAction(createQIconOnOffPNG("align_left"), |
| tr("Align Left"), m_alignActionGroup); |
| m_alignLeftAction->setCheckable(true); |
| m_alignCenterAction = new QAction(createQIconOnOffPNG("align_center"), |
| tr("Align Center"), m_alignActionGroup); |
| m_alignCenterAction->setCheckable(true); |
| m_alignRightAction = new QAction(createQIconOnOffPNG("align_right"), |
| tr("Align Right"), m_alignActionGroup); |
| m_alignRightAction->setCheckable(true); |
| } |
| |
| |
| |
| void DvTextEdit::createMiniToolBar() { |
| m_miniToolBar = new DvMiniToolBar(); |
| |
| QToolBar *toolBarUp = new QToolBar(m_miniToolBar); |
| toolBarUp->setIconSize(QSize(30, 30)); |
| toolBarUp->setObjectName("toolOptionBar"); |
| toolBarUp->setFixedHeight(30); |
| |
| m_fontComboBox = new QFontComboBox(toolBarUp); |
| m_fontComboBox->setMaximumHeight(20); |
| m_fontComboBox->setMinimumWidth(140); |
| |
| connect(m_fontComboBox, SIGNAL(activated(const QString &)), this, |
| SLOT(setTextFamily(const QString &))); |
| |
| m_sizeComboBox = new QComboBox(toolBarUp); |
| m_sizeComboBox->setEditable(true); |
| m_sizeComboBox->setMaximumHeight(20); |
| m_sizeComboBox->setMinimumWidth(44); |
| |
| QFontDatabase db; |
| foreach (int size, db.standardSizes()) |
| m_sizeComboBox->addItem(QString::number(size)); |
| |
| connect(m_sizeComboBox, SIGNAL(activated(const QString &)), this, |
| SLOT(setTextSize(const QString &))); |
| |
| toolBarUp->addWidget(m_fontComboBox); |
| toolBarUp->addWidget(m_sizeComboBox); |
| |
| QToolBar *toolBarDown = new QToolBar(m_miniToolBar); |
| toolBarDown->setIconSize(QSize(30, 30)); |
| toolBarDown->setObjectName("toolOptionBar"); |
| toolBarDown->setFixedHeight(30); |
| |
| toolBarDown->setIconSize(QSize(30, 30)); |
| |
| toolBarDown->addWidget(m_colorField); |
| toolBarDown->addSeparator(); |
| toolBarDown->addAction(m_boldAction); |
| toolBarDown->addAction(m_italicAction); |
| toolBarDown->addAction(m_underlineAction); |
| toolBarDown->addSeparator(); |
| toolBarDown->addActions(m_alignActionGroup->actions()); |
| |
| QVBoxLayout *m_mainLayout = new QVBoxLayout(m_miniToolBar); |
| m_mainLayout->setSizeConstraint(QLayout::SetFixedSize); |
| m_mainLayout->setMargin(2); |
| m_mainLayout->setSpacing(2); |
| m_mainLayout->addWidget(toolBarUp); |
| m_mainLayout->addWidget(toolBarDown); |
| |
| m_miniToolBar->setLayout(m_mainLayout); |
| } |
| |
| |
| |
| void DvTextEdit::mouseReleaseEvent(QMouseEvent *e) { |
| QTextEdit::mouseReleaseEvent(e); |
| |
| if (e->button() == Qt::LeftButton && m_miniToolBarEnabled) { |
| QTextCursor cursor = textCursor(); |
| |
| if (cursor.hasSelection()) { |
| cursor.setPosition(cursor.selectionEnd(), QTextCursor::MoveAnchor); |
| QRect r = cursorRect(cursor); |
| QPoint buttonPos = mapToGlobal(r.topRight()); |
| buttonPos.setX(buttonPos.x() - r.width() * 0.5 + 2); |
| buttonPos.setY(buttonPos.y() - (m_button->height() - r.height()) * 0.5); |
| m_button->move(buttonPos); |
| m_button->show(); |
| } |
| } |
| } |
| |
| |
| |
| void DvTextEdit::mousePressEvent(QMouseEvent *e) { |
| QTextEdit::mousePressEvent(e); |
| if (m_miniToolBarEnabled && m_miniToolBar->isVisible()) hideMiniToolBar(); |
| } |
| |
| |
| |
| void DvTextEdit::mouseMoveEvent(QMouseEvent *event) { |
| QTextEdit::mouseMoveEvent(event); |
| |
| m_mousePos = event->pos(); |
| } |
| |
| |
| |
| void DvTextEdit::wheelEvent(QWheelEvent *e) { |
| QTextEdit::wheelEvent(e); |
| m_button->hide(); |
| } |
| |
| |
| |
| void DvTextEdit::focusOutEvent(QFocusEvent *e) { |
| QTextEdit::focusOutEvent(e); |
| if (m_miniToolBar->isVisible() && !m_miniToolBar->underMouse()) { |
| hideMiniToolBar(); |
| } |
| m_button->hide(); |
| } |
| |
| |
| |
| void DvTextEdit::focusInEvent(QFocusEvent *e) { |
| QTextEdit::focusInEvent(e); |
| emit focusIn(); |
| } |
| |
| |
| |
| void DvTextEdit::dragMoveEvent(QDragMoveEvent *e) { |
| |
| if (m_miniToolBar->isVisible()) hideMiniToolBar(); |
| |
| m_button->hide(); |
| QTextEdit::dragMoveEvent(e); |
| } |
| |
| |
| |
| void DvTextEdit::showMiniToolBar(const QPoint &pos) { |
| if (m_miniToolBarEnabled) { |
| m_miniToolBar->move(pos); |
| m_miniToolBar->show(); |
| } |
| } |
| |
| |
| |
| void DvTextEdit::hideMiniToolBar() { |
| |
| m_miniToolBar->hide(); |
| |
| QTextCursor cursor = textCursor(); |
| } |
| |
| |
| |
| void DvTextEdit::setTextBold() { |
| QTextCharFormat fmt; |
| fmt.setFontWeight(m_boldAction->isChecked() ? QFont::Bold : QFont::Normal); |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| void DvTextEdit::setTextItalic() { |
| QTextCharFormat fmt; |
| fmt.setFontItalic(m_italicAction->isChecked()); |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| void DvTextEdit::setTextUnderline() { |
| QTextCharFormat fmt; |
| fmt.setFontUnderline(m_underlineAction->isChecked()); |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| void DvTextEdit::setTextColor(const TPixel32 &color, bool isDragging) { |
| if (isDragging) return; |
| QColor col(color.r, color.g, color.b, color.m); |
| QTextCharFormat fmt; |
| fmt.setForeground(col); |
| mergeFormatOnWordOrSelection(fmt); |
| colorChanged(col); |
| } |
| |
| |
| |
| void DvTextEdit::setTextFamily(const QString &f) { |
| QTextCharFormat fmt; |
| fmt.setFontFamily(f); |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| void DvTextEdit::setTextSize(const QString &p) { |
| QTextCharFormat fmt; |
| fmt.setFontPointSize(p.toFloat()); |
| mergeFormatOnWordOrSelection(fmt); |
| } |
| |
| |
| |
| void DvTextEdit::setTextAlign(QAction *a) { |
| if (a == m_alignLeftAction) |
| setAlignment(Qt::AlignLeft); |
| else if (a == m_alignCenterAction) |
| setAlignment(Qt::AlignHCenter); |
| else if (a == m_alignRightAction) |
| setAlignment(Qt::AlignRight); |
| } |
| |
| |
| |
| void DvTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { |
| QTextCursor cursor = textCursor(); |
| if (!cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); |
| cursor.mergeCharFormat(format); |
| mergeCurrentCharFormat(format); |
| emit textChanged(); |
| } |
| |
| |
| |
| void DvTextEdit::fontChanged(const QFont &f) { |
| m_fontComboBox->setCurrentIndex( |
| m_fontComboBox->findText(QFontInfo(f).family())); |
| m_sizeComboBox->setCurrentIndex( |
| m_sizeComboBox->findText(QString::number(f.pointSize()))); |
| m_boldAction->setChecked(f.bold()); |
| m_italicAction->setChecked(f.italic()); |
| m_underlineAction->setChecked(f.underline()); |
| } |
| |
| |
| |
| void DvTextEdit::colorChanged(const QColor &c) { |
| m_colorField->setColor(TPixel32(c.red(), c.green(), c.blue(), c.alpha())); |
| } |
| |
| |
| |
| void DvTextEdit::alignmentChanged(Qt::Alignment a) { |
| if (a & Qt::AlignLeft) { |
| m_alignLeftAction->setChecked(true); |
| } else if (a & Qt::AlignHCenter) { |
| m_alignCenterAction->setChecked(true); |
| } else if (a & Qt::AlignRight) { |
| m_alignRightAction->setChecked(true); |
| } |
| } |
| |
| |
| |
| void DvTextEdit::onCurrentCharFormatChanged(const QTextCharFormat &format) { |
| fontChanged(format.font()); |
| colorChanged(format.foreground().color()); |
| } |
| |
| |
| |
| void DvTextEdit::onCursorPositionChanged() { alignmentChanged(alignment()); } |
| |
| |
| |
| void DvTextEdit::onShowMiniToolBarClicked() { |
| showMiniToolBar(m_button->pos()); |
| } |
| |
| |
| |
| void DvTextEdit::onSelectionChanged() { |
| QTextCursor cursor = textCursor(); |
| if (!cursor.hasSelection()) m_button->hide(); |
| } |
| |
| |
| |