From c8b95daa6ea50fc220fc31f9416a1cab5d6d63f8 Mon Sep 17 00:00:00 2001 From: SeeLook <945374+SeeLook@users.noreply.github.com> Date: Thu, 18 Dec 2014 21:13:08 +0100 Subject: [PATCH] Position of exam tips moved by user is stored, added signal moved() to TgraphicsTip when it is moveble ane user is changing its pos, inline methods with real (scaled) tip size (from boundingRect()), fixed crash when start exam dialog is closed a few times. --- TODO | 5 +- changes | 1 + src/charts/tanalysdialog.cpp | 2 +- src/exam/tcanvas.cpp | 128 ++++++++---- src/exam/tcanvas.h | 207 +++++++++++--------- src/exam/texamexecutor.cpp | 12 +- src/exam/tquestiontip.cpp | 25 ++- src/exam/tquestiontip.h | 53 ++--- src/libs/core/graphics/tgraphicstexttip.cpp | 8 +- src/libs/core/graphics/tgraphicstexttip.h | 10 + src/libs/sound/trtaudio.cpp | 1 - src/main.cpp | 3 - src/mainwindow.cpp | 1 - 13 files changed, 277 insertions(+), 179 deletions(-) diff --git a/TODO b/TODO index a0dea2f6a..0a67b8081 100755 --- a/TODO +++ b/TODO @@ -28,7 +28,9 @@ Tcanvas - canvas has to recognize when widgets are hidden and doesn't start correct animations - move what_next/question tips to the right over guitar in single note mode + Scaling issues: +- when window goes back from maximized guitar is out of it - auto hidden tool bar remains big after decreased window size - Windows has problems with tool bar scaling and single mode note name size - piano brace size/position @@ -46,15 +48,16 @@ Charts: - points (notes) shadow changes with zoom - fix it - zoom with CTRL+scroll moves a chart as well - fix it - staff line disappears sometimes (when zoom is big) + - use of realW() & realH() of TgraphicsTip - revert to native style under MacOs when Qt5 - TscoreView and TscoreItem have to have Android compile scopes +s Tnote - overload + and - operators to raise/drop a note - make appropriate methods const ==== NEW FEATURES ================================================================ -- store movable exam tips position for every type of an answer - proxy corner widgets should be animated (if they remain live) - tidy key signature in note pixmap (width depends on accidentals number) - increase precision of exam timers - regressions risk... diff --git a/changes b/changes index 5d06f5aab..103bcf1e6 100644 --- a/changes +++ b/changes @@ -1,3 +1,4 @@ + - exam tips stores their position when moved by user BUGS FIXES - fixed a lot of small glitches Under the hood diff --git a/src/charts/tanalysdialog.cpp b/src/charts/tanalysdialog.cpp index 22a7b1640..41a7ec08d 100755 --- a/src/charts/tanalysdialog.cpp +++ b/src/charts/tanalysdialog.cpp @@ -316,7 +316,7 @@ void TanalysDialog::createActions() { m_inclWrongAct->setChecked(m_chartSetts.inclWrongAnsw); m_settButt = new QToolButton(this); - m_settButt->setIcon(QIcon(gl->path+"picts/systemsettings.png")); + m_settButt->setIcon(QIcon(gl->path + "picts/exam-settings.png")); m_settButt->setToolTip(tr("Settings of a chart")); m_settButt->setMenu(menu); m_settButt->setPopupMode(QToolButton::InstantPopup); diff --git a/src/exam/tcanvas.cpp b/src/exam/tcanvas.cpp index cce3499bf..2c1b879be 100644 --- a/src/exam/tcanvas.cpp +++ b/src/exam/tcanvas.cpp @@ -49,19 +49,21 @@ extern Tglobals *gl; -Tcanvas::Tcanvas(QGraphicsView* view, MainWindow* parent) : +Tcanvas::Tcanvas(QGraphicsView* view, Texam* exam, MainWindow* parent) : QObject(parent->centralWidget()), m_view(view), m_window(parent), m_certifyTip(0), - m_exam(0), + m_exam(exam), m_scale(1), m_flyEllipse(0), - m_timerToConfirm(new QTimer(this)) + m_timerToConfirm(new QTimer(this)), + m_minimizedQuestion(false) { m_scene = m_view->scene(); m_newSize = m_scene->sceneRect().size().toSize(); + m_prevSize = m_scene->sceneRect().size(); sizeChanged(); connect(m_scene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(sizeChangedDelayed(QRectF))); connect(m_timerToConfirm, SIGNAL(timeout()), this, SLOT(showConfirmTip())); @@ -190,6 +192,7 @@ void Tcanvas::whatNextTip(bool isCorrect, bool toCorrection) { m_whatTip->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); m_whatTip->setTipMovable(true); connect(m_whatTip, &TgraphicsTextTip::linkActivated, this, &Tcanvas::linkActivatedSlot); + connect(m_whatTip, &TgraphicsTextTip::moved, this, &Tcanvas::tipMoved); setWhatNextPos(); } @@ -213,13 +216,13 @@ void Tcanvas::showConfirmTip() { m_confirmTip->setTipMovable(true); m_confirmTip->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); connect(m_confirmTip, &TgraphicsTextTip::linkActivated, this, &Tcanvas::linkActivatedSlot); + connect(m_confirmTip, &TgraphicsTextTip::moved, this, &Tcanvas::tipMoved); setConfirmPos(); } } -void Tcanvas::questionTip(Texam* exam) { - m_exam = exam; +void Tcanvas::questionTip() { delete m_startTip; delete m_whatTip; delete m_outTuneTip; @@ -228,6 +231,14 @@ void Tcanvas::questionTip(Texam* exam) { m_guitarFree = m_questionTip->freeGuitar(); m_nameFree = m_questionTip->freeName(); m_scoreFree = m_questionTip->freeScore(); + m_tipPos = e_scoreOver; // score is visible always + if (m_nameFree && m_window->noteName && m_window->noteName->isVisible()) + m_tipPos = e_nameOver; + else if (m_scoreFree) + m_tipPos = e_scoreOver; + else if (m_guitarFree && m_window->guitar->isVisible()) + m_tipPos = e_guitarOver; + m_questionTip->setMinimized(m_minimizedQuestion); setQuestionPos(); } @@ -266,6 +277,7 @@ void Tcanvas::melodyTip() { m_scene->addItem(m_melodyTip); m_melodyTip->setTipMovable(true); m_melodyTip->setScale(m_scale); + connect(m_melodyTip, &TgraphicsTextTip::moved, this, &Tcanvas::tipMoved); setMelodyPos(); } @@ -395,6 +407,18 @@ const QRect& Tcanvas::getRect(TQAtype::Etype kindOf) { //################################################################################################# void Tcanvas::sizeChangedDelayed(const QRectF& newRect) { + QSizeF factor(newRect.width() / m_prevSize.width(), newRect.height() / m_prevSize.height()); + for (int i = 0; i < 3; ++i) { + if (!m_posOfQuestTips[i].isNull()) + m_posOfQuestTips[i] = QPointF(m_posOfQuestTips[i].x() * factor.width(), m_posOfQuestTips[i].y() * factor.height()); + if (!m_posOfWhatTips[i].isNull()) + m_posOfWhatTips[i] = QPointF(m_posOfWhatTips[i].x() * factor.width(), m_posOfWhatTips[i].y() * factor.height()); + } + if (!m_posOfConfirm.isNull()) + m_posOfConfirm = QPointF(m_posOfConfirm.x() * factor.width(), m_posOfConfirm.y() * factor.height()); + if (!m_posOfMelody.isNull()) + m_posOfMelody = QPointF(m_posOfMelody.x() * factor.width(), m_posOfMelody.y() * factor.height()); + m_prevSize = newRect.size(); m_newSize = newRect.size().toSize(); QTimer::singleShot(2, this, SLOT(sizeChanged())); } @@ -496,58 +520,57 @@ void Tcanvas::setPosOfTip(TgraphicsTextTip* tip) { QRect geoRect; if (m_nameFree) { // middle of the noteName geoRect = m_window->noteName->geometry(); - if (tip == m_whatTip) { - if (tip->boundingRect().width() * tip->scale() != m_window->width() * 0.4) - tip->setScale((m_window->width() * 0.4) / (tip->boundingRect().width() * tip->scale())); - if (tip->boundingRect().height() * tip->scale() > m_window->score->height()) - tip->setScale((qreal)(m_window->score->height()) / (tip->boundingRect().height())); - } } else if (m_scoreFree) {// on the score at its center geoRect = m_window->score->geometry(); - if (tip->boundingRect().width() * tip->scale() > m_window->score->width()) - tip->setScale((qMax((qreal)m_window->score->width(), m_window->width() / 3.0) / (tip->boundingRect().width()))); + fixWidthOverScore(tip); } else { // middle of the guitar geoRect = m_window->guitar->geometry(); } - tip->setPos(qMin(geoRect.x() + (geoRect.width() - tip->boundingRect().width() * tip->scale()) / 2, - m_window->width() - tip->boundingRect().width() * tip->scale() - 5.0), - qMin(geoRect.y() + (geoRect.height() - tip->boundingRect().height() * tip->scale()) / 2, - m_window->height() - tip->boundingRect().height() * tip->scale() - 5.0)); + tip->setPos(qMin(geoRect.x() + (geoRect.width() - tip->realW()) / 2, m_window->width() - tip->realW() - 5.0), + qMin(geoRect.y() + (geoRect.height() - tip->realH()) / 2, m_window->height() - tip->realH() - 5.0)); // qMin guards a tip position in scene boundaries } void Tcanvas::setResultPos() { - m_resultTip->setPos(m_scene->width() * 0.52 + (m_scene->width() * 0.48 - m_scale * m_resultTip->boundingRect().width()) / 2, - m_scene->height() * 0.01); + m_resultTip->setPos(m_scene->width() * 0.52 + (m_scene->width() * 0.48 - m_resultTip->realW()) / 2, m_scene->height() * 0.01); } void Tcanvas::setTryAgainPos() { QPointF tl(m_scene->width() * 0.6, m_scene->height() * 0.10); // top left of tip area if (m_resultTip) // place it below result tip - tl.setY(m_resultTip->pos().y() + m_resultTip->boundingRect().height() * m_resultTip->scale()); + tl.setY(m_resultTip->pos().y() + m_resultTip->realH()); m_tryAgainTip->setPos(tl.x() + (m_scene->width() * 0.4 - m_scale * m_tryAgainTip->boundingRect().width()) / 2, tl.y()); } void Tcanvas::setWhatNextPos() { int maxTipHeight = getMaxTipHeight(); - if (!m_nameFree && m_whatTip->boundingRect().height() * m_whatTip->scale() != maxTipHeight) - m_whatTip->setScale((qreal)maxTipHeight / (m_whatTip->boundingRect().height() * m_whatTip->scale())); - setPosOfTip(m_whatTip); + if (!m_nameFree && m_whatTip->realH() != maxTipHeight) + m_whatTip->setScale((qreal)maxTipHeight / m_whatTip->realH()); + if (m_tipPos == e_nameOver) { + if (m_whatTip->realW() != m_window->width() * 0.5) + m_whatTip->setScale((m_window->width() * 0.5) / m_whatTip->realW()); + if (m_whatTip->realH() > m_window->score->height()) + m_whatTip->setScale((qreal)(m_window->score->height()) / m_whatTip->realH()); + } else + fixWidthOverScore(m_whatTip); + if (m_posOfWhatTips[(int)m_tipPos].isNull()) // calculate tip position only when user doesn't change it + setPosOfTip(m_whatTip); + else + m_whatTip->setFixPos(m_posOfWhatTips[(int)m_tipPos]); } void Tcanvas::setStartTipPos() { // in the middle of a window - m_startTip->setPos((m_scene->width() - m_scale * (m_startTip->boundingRect().width())) / 2, - (m_scene->height() - m_scale * (m_startTip->boundingRect().height())) / 2 ); + m_startTip->setPos((m_scene->width() - m_startTip->realW()) / 2, (m_scene->height() - m_startTip->realH()) / 2); } void Tcanvas::setConfirmPos() { // right top corner - m_confirmTip->setPos(m_window->width() - m_confirmTip->boundingRect().width() * m_confirmTip->scale() - 20, 20); + m_confirmTip->setPos(m_window->width() - m_confirmTip->realW() - 20, 20); } @@ -556,6 +579,8 @@ void Tcanvas::createQuestionTip() { m_questionTip = new TquestionTip(m_exam, m_scale * 1.2); m_questionTip->setTextWidth(m_maxTipWidth); m_scene->addItem(m_questionTip); + connect(m_questionTip, &TquestionTip::moved, this, &Tcanvas::tipMoved); + connect(m_questionTip, &TquestionTip::minimizeChanged, this, &Tcanvas::tipStateChanged); } @@ -565,7 +590,7 @@ void Tcanvas::setQuestionPos() { if (m_questionTip->boundingRect().height() > maxTipHeight) { // check is scaling needed fineScale = (qreal)maxTipHeight / m_questionTip->boundingRect().height(); qreal scaleStep = 0.0; - while (m_questionTip->boundingRect().height() * m_questionTip->scale() > maxTipHeight) { + while (m_questionTip->realH() > maxTipHeight) { delete m_questionTip; m_questionTip = new TquestionTip(m_exam, fineScale - scaleStep); m_questionTip->setTextWidth(m_maxTipWidth); @@ -573,28 +598,32 @@ void Tcanvas::setQuestionPos() { scaleStep += 0.1; } } - setPosOfTip(m_questionTip); + if (m_posOfQuestTips[(int)m_tipPos].isNull()) // calculate tip position only when user doesn't change it + setPosOfTip(m_questionTip); + else { + fixWidthOverScore(m_questionTip); + m_questionTip->setFixPos(m_posOfQuestTips[(int)m_tipPos]); + } m_questionTip->show(); } void Tcanvas::setOutTunePos() { int startX = m_window->pitchView->geometry().x(); - if (m_outTuneTip->boundingRect().width() * m_outTuneTip->scale() > m_window->pitchView->geometry().width() / 2) - m_outTuneTip->setScale((m_outTuneTip->boundingRect().width() * m_outTuneTip->scale()) / - (m_window->pitchView->geometry().width() / 2)); + if (m_outTuneTip->realW() > m_window->pitchView->geometry().width() / 2) + m_outTuneTip->setScale(m_outTuneTip->realW() / (m_window->pitchView->geometry().width() / 2)); if (!m_outTuneTip->data(0).toBool()) startX += m_window->pitchView->geometry().width() / 2; - m_outTuneTip->setPos(startX + (m_window->pitchView->geometry().width() / 2 - m_outTuneTip->boundingRect().width()) / 2, - m_window->pitchView->y() - m_outTuneTip->boundingRect().height() * m_outTuneTip->scale()); + m_outTuneTip->setPos(startX + (m_window->pitchView->geometry().width() / 2 - m_outTuneTip->realW()) / 2, + m_window->pitchView->y() - m_outTuneTip->realH()); } void Tcanvas::setMelodyPos() { - m_melodyTip->setPos(10.0, - m_window->score->pos().y() + m_window->score->height() - - m_melodyTip->scale() * m_melodyTip->boundingRect().height() - 5.0); -// m_melodyTip->setPos(m_view->width() - m_melodyTip->boundingRect().width() * m_melodyTip->scale() - 10.0, 5.0); + if (m_posOfMelody.isNull()) + m_melodyTip->setPos(10.0, m_window->score->pos().y() + m_window->score->height() - m_melodyTip->realH() - 5.0); + else + m_melodyTip->setPos(m_posOfMelody); } @@ -604,6 +633,31 @@ void Tcanvas::updateRelatedPoint() { } +void Tcanvas::fixWidthOverScore ( TgraphicsTextTip* tip ) { + if (m_tipPos == e_scoreOver && tip->realW() > m_window->score->width()) + tip->setScale((qMax((qreal)m_window->score->width(), m_window->width() / 3.0) / (tip->boundingRect().width()))); +} + + + +void Tcanvas::tipMoved() { + if (sender() == m_questionTip) + m_posOfQuestTips[(int)m_tipPos] = m_questionTip->pos(); + else if (sender() == m_whatTip) + m_posOfWhatTips[(int)m_tipPos] = m_whatTip->pos(); + else if (sender() == m_confirmTip) + m_posOfConfirm = m_confirmTip->pos(); + else if (sender() == m_melodyTip) + m_posOfMelody = m_melodyTip->pos(); +} + + +void Tcanvas::tipStateChanged() { + if (sender() == m_questionTip) + m_minimizedQuestion = m_questionTip->isMinimized(); +} + + diff --git a/src/exam/tcanvas.h b/src/exam/tcanvas.h index ffa4fd904..55b64280b 100644 --- a/src/exam/tcanvas.h +++ b/src/exam/tcanvas.h @@ -43,7 +43,7 @@ class TgraphicsTextTip; /** * This class managing Nootka main View - * to show notifications during an exam. + * to show notifications (tips) during an exam. */ class Tcanvas : public QObject { @@ -53,109 +53,122 @@ class Tcanvas : public QObject Q_OBJECT public: - Tcanvas(QGraphicsView* view, MainWindow *parent); - virtual ~Tcanvas(); - - void addTip(TgraphicsTextTip *tip); // add any TgraphicsTextTip object - void resultTip(TQAunit *answer, int time = 0); // show was question correct text, hides after given time - void startTip(); // Text with help on an exam start - - /** Text with what to click after an answer. - * @p isCorrect - was the question correct - * @p toCorrection - text how to see corrected answer will be shown. */ - void whatNextTip(bool isCorrect, bool toCorrection = false); - void questionTip(Texam *exam); // Text with question context - void tryAgainTip(int time); // "Try again" text" - void confirmTip(int time = 0); // tip about confirm an answer appears after given time - void certificateTip(); // paper like exam report when finished - void melodyTip(); // How to get hints about corrected melody notes - - /** 'to low' or 'to high' text above pitch view @p pitchDiff is float part of pitch */ - void outOfTuneTip(float pitchDiff); - - /** Manages an animation of correcting answer as played sound. - * Correct position on the guitar is displayed - * and start point on the animation depends on question type. */ - void correctToGuitar(TQAtype::Etype& question, int prevTime, TfingerPos& goodPos); - - void clearCanvas(); - - /** Returns point size of 'A' letter multiplied by 2. */ - int bigFont(); - - /** Returns default font with point size scaled to 'A' letter multiplied by given factor. */ - QFont tipFont(qreal factor = 1); - QString startTipText(); - - /** Paints animated exclamation mark over answering widget. */ - void markAnswer(TQAtype::Etype qType, TQAtype::Etype aType); - - /** Paints rectangle around given type of widget to mark where is answer. */ - const QRect& getRect(TQAtype::Etype kindOf); - - /** Displays message on main window status label with given note as the detected. */ - void detectedNoteTip(const Tnote& note); - + + enum EtipPos { + e_guitarOver = 0, e_scoreOver = 1, e_nameOver = 2 + }; /** Describes a kind of tip position depended on q/a type - over what widget tip is placed */ + + Tcanvas(QGraphicsView* view, Texam* exam, MainWindow *parent); + virtual ~Tcanvas(); + + void addTip(TgraphicsTextTip *tip); // add any TgraphicsTextTip object + void resultTip(TQAunit *answer, int time = 0); // show was question correct text, hides after given time + void startTip(); // Text with help on an exam start + + /** Text with what to click after an answer. + * @p isCorrect - was the question correct + * @p toCorrection - text how to see corrected answer will be shown. */ + void whatNextTip(bool isCorrect, bool toCorrection = false); + void questionTip(); // Text with question context + void tryAgainTip(int time); // "Try again" text" + void confirmTip(int time = 0); // tip about confirm an answer appears after given time + void certificateTip(); // paper like exam report when finished + void melodyTip(); // How to get hints about corrected melody notes + + /** 'to low' or 'to high' text above pitch view @p pitchDiff is float part of pitch */ + void outOfTuneTip(float pitchDiff); + + /** Manages an animation of correcting answer as played sound. + * Correct position on the guitar is displayed + * and start point on the animation depends on question type. */ + void correctToGuitar(TQAtype::Etype& question, int prevTime, TfingerPos& goodPos); + + void clearCanvas(); + + /** Returns point size of 'A' letter multiplied by 2. */ + int bigFont(); + + /** Returns default font with point size scaled to 'A' letter multiplied by given factor. */ + QFont tipFont(qreal factor = 1); + QString startTipText(); + + /** Paints animated exclamation mark over answering widget. */ + void markAnswer(TQAtype::Etype qType, TQAtype::Etype aType); + + /** Paints rectangle around given type of widget to mark where is answer. */ + const QRect& getRect(TQAtype::Etype kindOf); + + /** Displays message on main window status label with given note as the detected. */ + void detectedNoteTip(const Tnote& note); + public slots: - void clearResultTip(); // clears tip with results - void clearTryAgainTip(); - void linkActivatedSlot(const QString& link); - void clearConfirmTip(); - void showConfirmTip(); - void clearCertificate(); - void clearCorrection(); - void clearWhatNextTip(); - + void clearResultTip(); // clears tip with results + void clearTryAgainTip(); + void linkActivatedSlot(const QString& link); + void clearConfirmTip(); + void showConfirmTip(); + void clearCertificate(); + void clearCorrection(); + void clearWhatNextTip(); + signals: - void buttonClicked(const QString&); /** This signal is emitted when user click image button (a link) on any tip.*/ - void certificateMagicKeys(); /** When translator wants to see a certificate preview */ - + void buttonClicked(const QString&); /** This signal is emitted when user click image button (a link) on any tip.*/ + void certificateMagicKeys(); /** When translator wants to see a certificate preview */ + protected: - virtual bool eventFilter(QObject* obj, QEvent* event); - + virtual bool eventFilter(QObject* obj, QEvent* event); + + protected slots: - /** Calls sizeChanged with delay to allow MainWindow deploy its new geometry. */ - void sizeChangedDelayed(const QRectF& newRect); - void sizeChanged(); - void correctAnimFinished(); - - + /** Calls sizeChanged with delay to allow MainWindow deploy its new geometry. */ + void sizeChangedDelayed(const QRectF& newRect); + void sizeChanged(); + void correctAnimFinished(); + + private: - MainWindow *m_window; - QGraphicsView *m_view; - QGraphicsScene *m_scene; - double m_scale; - QPointer<TgraphicsTextTip> m_resultTip, m_whatTip, m_startTip, m_tryAgainTip; - QPointer<TgraphicsTextTip> m_confirmTip, m_outTuneTip, m_melodyTip; - QPointer<TquestionTip> m_questionTip; - QPointer<TnootkaCertificate> m_certifyTip; - Texam *m_exam; - QPointer<TcombinedAnim> m_correctAnim; - QTimer *m_timerToConfirm; - int m_maxTipWidth; - bool m_guitarFree, m_nameFree, m_scoreFree; - QSize m_newSize; - QGraphicsEllipseItem *m_flyEllipse; - TfingerPos m_goodPos; - QColor m_correctColor; - TnoteName *m_noteName; - QPoint m_relPoint; - - + MainWindow *m_window; + QGraphicsView *m_view; + QGraphicsScene *m_scene; + double m_scale; + QPointer<TgraphicsTextTip> m_resultTip, m_whatTip, m_startTip, m_tryAgainTip; + QPointer<TgraphicsTextTip> m_confirmTip, m_outTuneTip, m_melodyTip; + QPointer<TquestionTip> m_questionTip; + QPointer<TnootkaCertificate> m_certifyTip; + Texam *m_exam; + QPointer<TcombinedAnim> m_correctAnim; + QTimer *m_timerToConfirm; + int m_maxTipWidth; + bool m_guitarFree, m_nameFree, m_scoreFree; + QSizeF m_prevSize; + QSize m_newSize; + QGraphicsEllipseItem *m_flyEllipse; + TfingerPos m_goodPos; + QColor m_correctColor; + TnoteName *m_noteName; + QPoint m_relPoint; + QPointF m_posOfQuestTips[3], m_posOfWhatTips[3], m_posOfConfirm, m_posOfMelody; + bool m_minimizedQuestion; + EtipPos m_tipPos; /** Kind of tip position */ + private: - int getMaxTipHeight(); /** Calculates maximal tip height depends on free MainWindow widget. */ - void setPosOfTip(TgraphicsTextTip *tip); /** Universal method to place given tip above free MainWindow widget. */ - void setResultPos(); - void setWhatNextPos(); - void setStartTipPos(); - void setQuestionPos(); - void setTryAgainPos(); - void setConfirmPos(); - void setOutTunePos(); - void updateRelatedPoint(); - void setMelodyPos(); - void createQuestionTip(); /** Be sure that @p m_exam has already pointed current exam */ + int getMaxTipHeight(); /** Calculates maximal tip height depends on free MainWindow widget. */ + void setPosOfTip(TgraphicsTextTip *tip); /** Universal method to place given tip above free MainWindow widget. */ + void setResultPos(); + void setWhatNextPos(); + void setStartTipPos(); + void setQuestionPos(); + void setTryAgainPos(); + void setConfirmPos(); + void setOutTunePos(); + void updateRelatedPoint(); + void setMelodyPos(); + void createQuestionTip(); /** Be sure that @p m_exam has already pointed current exam */ + void fixWidthOverScore(TgraphicsTextTip* tip); /** Scales tip if its width is bigger than score widget */ + + void tipMoved(); /** It is used as a slot to store position of a tip moved by user */ + void tipStateChanged(); /** It is used as a slot to store minimization state of a tip. */ }; diff --git a/src/exam/texamexecutor.cpp b/src/exam/texamexecutor.cpp index a255c955f..a20086048 100755 --- a/src/exam/texamexecutor.cpp +++ b/src/exam/texamexecutor.cpp @@ -73,6 +73,7 @@ TexamExecutor::TexamExecutor(MainWindow *mainW, QString examFile, Tlevel *lev) : m_snifferLocked(false), m_canvas(0), m_supp(0), + m_penalty(0), m_exercise(0), m_blindCounter(0), m_rand(0) @@ -184,10 +185,13 @@ TexamExecutor::TexamExecutor(MainWindow *mainW, QString examFile, Tlevel *lev) : TexamExecutor::~TexamExecutor() { + if (m_penalty) + delete m_penalty; if (m_supp) delete m_supp; - delete m_penalty; delete m_glStore; + if (m_rand) + delete m_rand; deleteExam(); } @@ -482,7 +486,7 @@ void TexamExecutor::askQuestion(bool isAttempt) { mW->bar->setForQuestion(curQ.questionAsSound(), curQ.questionAsSound() && curQ.answerAsNote()); m_penalty->startQuestionTime(); - m_canvas->questionTip(m_exam); + m_canvas->questionTip(); m_blindCounter = 0; // question successfully asked - reset the counter } @@ -924,7 +928,7 @@ void TexamExecutor::repeatQuestion() { mW->bar->setForQuestion(curQ.questionAsSound(), curQ.questionAsSound() && curQ.answerAsNote()); if (curQ.questionAsSound()) repeatSound(); - m_canvas->questionTip(m_exam); + m_canvas->questionTip(); m_penalty->startQuestionTime(); } @@ -1018,7 +1022,7 @@ void TexamExecutor::prepareToExam() { } } m_snifferLocked = false; - m_canvas = new Tcanvas(mW->innerWidget, mW); + m_canvas = new Tcanvas(mW->innerWidget, m_exam, mW); connect(m_canvas, &Tcanvas::buttonClicked, this, &TexamExecutor::tipButtonSlot); if (m_level.canBeMelody() && m_level.answerIsSound()) mW->sound->enableStoringNotes(true); diff --git a/src/exam/tquestiontip.cpp b/src/exam/tquestiontip.cpp index 86ab85ede..4c376c7ea 100644 --- a/src/exam/tquestiontip.cpp +++ b/src/exam/tquestiontip.cpp @@ -30,6 +30,7 @@ #include <tnoofont.h> #include <QPainter> #include <QGraphicsSceneMouseEvent> +#include <QGraphicsScene> // #include <QDebug> @@ -255,6 +256,21 @@ QString TquestionTip::getQuestion(TQAunit& question, int questNr, Tlevel* level, } +void TquestionTip::setMinimized(bool min) { + if (min != m_minimized) { + m_minimized = min; + if (m_minimized) { + QString titleText = m_questText.mid(0, m_questText.indexOf("<br>") - 1); + setHtml(titleText); + } else { + setHtml(m_questText); + } + setFixPos(pos()); + } +} + + + void TquestionTip::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { QRectF rect = boundingRect(); // background rectangle with question color border @@ -313,13 +329,8 @@ void TquestionTip::hoverMoveEvent(QGraphicsSceneHoverEvent* event) { void TquestionTip::mousePressEvent(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton) { if (m_markCorner) { - m_minimized = !m_minimized; - if (m_minimized) { - QString titleText = m_questText.mid(0, m_questText.indexOf("<br>") - 1); - setHtml(titleText); - } else { - setHtml(m_questText); - } + setMinimized(!m_minimized); + emit minimizeChanged(); } } TgraphicsTextTip::mousePressEvent(event); diff --git a/src/exam/tquestiontip.h b/src/exam/tquestiontip.h index e9f444cb8..f972d191b 100644 --- a/src/exam/tquestiontip.h +++ b/src/exam/tquestiontip.h @@ -30,39 +30,46 @@ class TQAunit; /** * This is graphics tip (rectangle) representing a question context + * It can be minimized with mouse. */ class TquestionTip : public TgraphicsTextTip { Q_OBJECT public: - /** Constructs tip with question content. */ - TquestionTip(Texam *exam, double scale = 0); - ~TquestionTip(); - - static QString getTextHowAccid(Tnote::Ealter accid); - static QString onStringTxt(quint8 strNr); /** Returns translated text on (strNr) string in Nootka font. */ - - /** Depend on @p instrument it returns text: - * 'Play or sing' (other instrument) - * 'Play' (guitars) */ - static QString playOrSing(int instr); - - static QString& text() { return m_questText; } /** Returns a reference to question HTML string. */ - - bool freeScore() { return m_scoreFree; } /** true when question is not on score */ - bool freeName() { return m_nameFree; } /** true when question is not on note name */ - bool freeGuitar() { return m_guitarFree; } /** true when question is not on guitar */ + /** Constructs tip with question content. */ + TquestionTip(Texam *exam, double scale = 0); + ~TquestionTip(); + + static QString getTextHowAccid(Tnote::Ealter accid); + static QString onStringTxt(quint8 strNr); /** Returns translated text on (strNr) string in Nootka font. */ + + /** Depend on @p instrument it returns text: + * 'Play or sing' (other instrument) + * 'Play' (guitars) */ + static QString playOrSing(int instr); + + static QString& text() { return m_questText; } /** Returns a reference to question HTML string. */ + + bool freeScore() { return m_scoreFree; } /** true when question is not on score */ + bool freeName() { return m_nameFree; } /** true when question is not on note name */ + bool freeGuitar() { return m_guitarFree; } /** true when question is not on guitar */ + + bool isMinimized() { return m_minimized; } /** True when tip is minimized */ + void setMinimized(bool min); /** Minimizes of maximizes a tip */ - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); - virtual QRectF boundingRect() const; + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + virtual QRectF boundingRect() const; + + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); - virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event); - virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); +signals: + void minimizeChanged(); /** Emitted when tips gets minimized or restored to normal state */ protected: - /** Returns html-formated question text. */ + /** Returns html-formatted question text. */ QString getQuestion(TQAunit &question, int questNr, Tlevel *level, double scale = 0); QString getNiceNoteName(Tnote& note, Tnote::EnameStyle style); diff --git a/src/libs/core/graphics/tgraphicstexttip.cpp b/src/libs/core/graphics/tgraphicstexttip.cpp index 99e4b6391..85a181647 100644 --- a/src/libs/core/graphics/tgraphicstexttip.cpp +++ b/src/libs/core/graphics/tgraphicstexttip.cpp @@ -24,7 +24,6 @@ #include <QPainter> #include <QGraphicsSceneHoverEvent> #include <QApplication> -#include <QGraphicsScene> // #include <QDebug> @@ -176,9 +175,10 @@ void TgraphicsTextTip::mousePressEvent(QGraphicsSceneMouseEvent* event) { void TgraphicsTextTip::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { if (isMovable() && event->buttons() == Qt::LeftButton) { - if (!m_lastPos.isNull()) - setPos(qBound(0.0, x() + event->scenePos().x() - m_lastPos.x(), scene()->width() - boundingRect().width() * scale()), - qBound(0.0, y() + event->scenePos().y() - m_lastPos.y(), scene()->height() - boundingRect().height() * scale())); + if (!m_lastPos.isNull()) { + setFixPos(x() + event->scenePos().x() - m_lastPos.x(), y() + event->scenePos().y() - m_lastPos.y()); + emit moved(); + } m_lastPos = event->scenePos(); } QGraphicsTextItem::mouseMoveEvent(event); diff --git a/src/libs/core/graphics/tgraphicstexttip.h b/src/libs/core/graphics/tgraphicstexttip.h index 71a6fd8e6..4bc44be7b 100644 --- a/src/libs/core/graphics/tgraphicstexttip.h +++ b/src/libs/core/graphics/tgraphicstexttip.h @@ -21,6 +21,7 @@ #include <nootkacoreglobal.h> #include <QGraphicsItem> +#include <QGraphicsScene> /** @@ -45,6 +46,14 @@ public: virtual QRectF boundingRect() const; void setHtml(QString htmlText); /** Overwrites QGraphicsTextItem method and make given text centered. */ + + qreal realW() { return boundingRect().width() * scale(); } /** boundingRect().width() * scale() */ + qreal realH() { return boundingRect().height() * scale(); } /** boundingRect().height() * scale() */ + + void setFixPos(qreal xx, qreal yy) { + setPos(qBound(2.0, xx, scene()->width() - realW() - 5.0), qBound(2.0, yy, scene()->height() - realH() - 5.0)); + } /** Sets current position respecting scene bounding rectangle. */ + void setFixPos(const QPointF& pp) { setFixPos(pp.x(), pp.y()); } QColor bgColor() { return m_bgColor; } /** Background color of tip */ void setBgColor(QColor col); /** Sets background color of tip */ @@ -64,6 +73,7 @@ public: signals: void clicked(); /** When item was clicked but doesn't move */ + void moved(); /** When item was moved by user. setPoS() doesn't invoke it! */ protected: virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event); diff --git a/src/libs/sound/trtaudio.cpp b/src/libs/sound/trtaudio.cpp index 66e3d4479..fee31a298 100755 --- a/src/libs/sound/trtaudio.cpp +++ b/src/libs/sound/trtaudio.cpp @@ -223,7 +223,6 @@ TrtAudio::~TrtAudio() streamOptions = 0; delete m_ao; m_ao = 0; - qDebug() << "RtAudio instance totally deleted"; } } diff --git a/src/main.cpp b/src/main.cpp index 2c23d48d3..bdd77587d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,10 +74,7 @@ int main(int argc, char *argv[]) firstTime = false; exitCode = a->exec(); delete w; - qDebug() << "Main Window successfully deleted"; } while (resetConfig); -// delete gl; -// qDebug() << "Settings object successfully deleted"; return exitCode; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3fbb021ae..f0b5998d4 100755 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -204,7 +204,6 @@ MainWindow::~MainWindow() gl->config->setValue("geometry", geometry()); gl->config->endGroup(); delete gl; - qDebug() << "Settings object successfully deleted"; } //########################################################################################## -- GitLab