#include "toonzqt/dvtextedit.h" #include "toonzqt/gutil.h" #include #include #include #include #include #include #include #include #include #include #include #include #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::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::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::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(); //bool aux = fmt.fontUnderline(); fmt.setFont(f); //fmt.setFontHintingPreference(QFont::PreferFullHinting); 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) { // Se inizio un drag e la toolbar รจ visibile la nascondo 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() { // Hide the miniToolBar m_miniToolBar->hide(); // Store the current Font in the application 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(); } //-----------------------------------------------------------------------------