diff --git a/TODO b/TODO index a0dea2f6a16ea9606d4461c23eb9faa988be057f..0a67b80811acee76524c713751e4296e1ec0b4bb 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 5d06f5aab67d9727bd241b37a8e5547eb1c7c54d..103bcf1e6e7cbd984ec8a459556cbbdef9f95765 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 22a7b1640266279663f48ad9ae1b2b5a6fa884c2..41a7ec08d86b53f30575d9bc1452bcd6a6fc21ba 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 cce3499bf2f1daf28d72cea8daab0dd1099c32fe..2c1b879be78e01e0f02f735eb73a44b58e23c328 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 ffa4fd904a321f26a472451e29681843248ff4f3..55b64280b19d02d59446e6137a79b62ff4165865 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 a255c955f020aca857d41d0f62e21f7ac74bd3d6..a20086048c1998c7dfab95f130a46df1aee80d2f 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 86ab85ede6eb8d03cbace8da67efa49596f623b2..4c376c7ea05b938574697baaf5132048a7b7215c 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 e9f444cb8bc2eeb1438863b27a03d7a938275e66..f972d191b34cc4253ecab34d2546704d64a7d306 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 99e4b6391b672a7cdcdd92b68ed691ca872e0703..85a1816476a181acb1f4ba879fdd88236d76c751 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 71a6fd8e6e5dd268f976b49fdd976515ec52d5d0..4bc44be7bde712a69fc494f2b98d4f4d639ef4b3 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 66e3d44793f1b9ac0fcc6a11bffc44b4e64bb97c..fee31a298a8f887f01f75166df17490f8eff0ec2 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 2c23d48d3c8fb5d436f5951cf980feda68a86274..bdd77587d1f469fc7d4b2d9efcd1a24d1ee5abf5 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 3fbb021ae8e019b2b5824e9d56e97e250b02513d..f0b5998d4cbeb5eb23e073f6485c40299e151e2f 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"; } //##########################################################################################