diff --git a/src/Cfg.cpp b/src/Cfg.cpp index 3ccf1582..bbdfe87f 100644 --- a/src/Cfg.cpp +++ b/src/Cfg.cpp @@ -45,3 +45,34 @@ int Cfg::tickRate; const int Cfg::m_playZoneEarly = 25; // Was 25 const int Cfg::m_playZoneLate = 25; + +ColorTheme Cfg::m_colorTheme; + +void ColorTheme::load(BuiltInColorTheme builtInColorTheme) +{ + switch (builtInColorTheme) { + case BuiltInColorTheme::Light: + menuColor = CColor(0.1, 0.6, 0.6); + menuSelectedColor = CColor(0.7, 0.7, 0.1); + staveColor = CColor(0.2, 0.2, 0.2); + staveColorDim = CColor(0.25, 0.40, 0.25); // grey + noteColor = CColor(0.0, 0.0, 0.0); // black + noteColorDim = CColor(0.4, 0.4, 0.4); // grey + playedGoodColor = CColor(0.5, 0.6, 1.0); // purple + playedBadColor = CColor(0.8, 0.3, 0.8); // orange + playedStoppedColor = CColor(1.0, 0.8, 0.0); // bright orange + backgroundColor = CColor(1.0, 1.0, 1.0); // white + barMarkerColor = CColor(0.5, 0.5, 0.5); // grey + beatMarkerColor = CColor(0.25, 0.25, 0.25); // grey + pianoGoodColor = playedGoodColor; + pianoBadColor = CColor(1.0, 0.0, 0.0); + noteNameColor = CColor(0.0, 0.0, 0.0); + playingZoneBg = CColor(0.75f, 0.75f, 1.0f); + playingZoneMiddle = CColor(0.0f, 0.0f, 0.4f); + playingZoneBorder = CColor(0.0f, 0.0f, 0.8f); + textColor = CColor(0.0, 0.0, 0.0); // black + break; + default: + *this = ColorTheme(); + } +} diff --git a/src/Cfg.h b/src/Cfg.h index 2bd01c80..acf53c57 100644 --- a/src/Cfg.h +++ b/src/Cfg.h @@ -66,6 +66,39 @@ class CColor } }; +enum class BuiltInColorTheme { + Default, + Light, +}; + +struct ColorTheme +{ + constexpr ColorTheme() = default; + ColorTheme &operator=(const ColorTheme &other) = default; + void load(BuiltInColorTheme builtInColorTheme); + + CColor menuColor = CColor(0.1, 0.6, 0.6); + CColor menuSelectedColor = CColor(0.7, 0.7, 0.1); + + CColor staveColor = CColor(0.1, 0.7, 0.1); // green + CColor staveColorDim = CColor(0.15, 0.40, 0.15); // grey + CColor noteColor = CColor(0.1, 0.9, 0.1); // green + CColor noteColorDim = CColor(0.25, 0.45, 0.25); // green + CColor playedGoodColor = CColor(0.5, 0.6, 1.0); // purple + CColor playedBadColor = CColor(0.8, 0.3, 0.8); // orange + CColor playedStoppedColor = CColor(1.0, 0.8, 0.0); // bright orange + CColor backgroundColor = CColor(0.0, 0.0, 0.0); // black + CColor barMarkerColor = CColor(0.3, 0.25, 0.25); // grey + CColor beatMarkerColor = CColor(0.25, 0.2, 0.2); // grey + CColor pianoGoodColor = playedGoodColor; + CColor pianoBadColor = CColor(1.0, 0.0, 0.0); + CColor noteNameColor = CColor(1.0, 1.0, 1.0); + CColor playingZoneBg = CColor(0.0f, 0.0f, 0.3f); + CColor playingZoneMiddle = CColor(0.0f, 0.0f, 0.8f); + CColor playingZoneBorder = CColor(0.0f, 0.0f, 0.6f); + CColor textColor = CColor(1.0f, 1.0f, 1.0f); +}; + /*! * @brief Contains all the configuration Information. */ @@ -89,23 +122,8 @@ class Cfg static int chordNoteGap() {return 10;} // all notes in a cord must be spaced less than this a gap static int chordMaxLength() {return 20;} // the max time between the start and end of a cord - static CColor menuColor() {return CColor(0.1, 0.6, 0.6);} - static CColor menuSelectedColor(){return CColor(0.7, 0.7, 0.1);} - - static CColor staveColor() {return CColor(0.1, 0.7, 0.1);} // green - static CColor staveColorDim() {return CColor(0.15, 0.40, 0.15);} // grey - static CColor noteColor() {return CColor(0.1, 0.9, 0.1);} // green - static CColor noteColorDim() {return CColor(0.25, 0.45, 0.25);} // green - //static CColor playedGoodColor() {return CColor(0.6, 0.6, 1.0);} // grey - static CColor playedGoodColor() {return CColor(0.5, 0.6, 1.0);} // purple 0.6, 0.6, 1.0 - static CColor playedBadColor() {return CColor(0.8, 0.3, 0.8);} // orange 0.7, 0.0, 0.0 - static CColor playedStoppedColor() {return CColor(1.0, 0.8, 0.0);} // bright orange - static CColor backgroundColor() {return CColor(0.0, 0.0, 0.0);} // black - static CColor barMarkerColor() {return CColor(0.3, 0.25, 0.25);} // grey - static CColor beatMarkerColor() {return CColor(0.25, 0.2, 0.2);} // grey - static CColor pianoGoodColor() {return playedGoodColor();} - static CColor pianoBadColor() {return CColor(1.0, 0.0, 0.0);} - static CColor noteNameColor() {return CColor(1.0, 1.0, 1.0);} + static const ColorTheme &colorTheme() { return m_colorTheme; } + static void loadColorTheme(BuiltInColorTheme builtInColorTheme) { m_colorTheme.load(builtInColorTheme); } static void setDefaults() { #ifdef _WIN32 @@ -148,6 +166,7 @@ class Cfg static int m_appX, m_appY, m_appWidth, m_appHeight; static const int m_playZoneEarly; static const int m_playZoneLate; + static ColorTheme m_colorTheme; }; #endif //__CFG_H__ diff --git a/src/Conductor.cpp b/src/Conductor.cpp index 28ad691d..612df8af 100644 --- a/src/Conductor.cpp +++ b/src/Conductor.cpp @@ -647,7 +647,7 @@ void CConductor::pianistInput(CMidiEvent inputNote) else pianistTiming = NOT_USED; m_scoreWin->setPlayedNoteColor(inputNote.note(), - (!m_followPlayingTimeOut)? Cfg::playedGoodColor():Cfg::playedBadColor(), + (!m_followPlayingTimeOut)? Cfg::colorTheme().playedGoodColor : Cfg::colorTheme().playedBadColor, m_chordDeltaTime, pianistTiming); if (validatePianistChord() == true) @@ -688,7 +688,7 @@ void CConductor::pianistInput(CMidiEvent inputNote) else // Hitting bad notes within the zone (so register them) { // Register the wrong note in the ratings calculation (if not as missed notes, I don't believe it's factored in) - missedNotesColor(Cfg::pianoBadColor()); + missedNotesColor(Cfg::colorTheme().pianoBadColor); m_rating.lateNotes(m_wantedChord.length() - m_goodPlayedNotes.length()); setEventBits(EVENT_BITS_forceRatingRedraw); fetchNextChord(); // Skip through the wrong note and continue to the next @@ -704,7 +704,7 @@ void CConductor::pianistInput(CMidiEvent inputNote) else pianistTiming = NOT_USED; m_scoreWin->setPlayedNoteColor(inputNote.note(), - (!m_followPlayingTimeOut)? Cfg::playedGoodColor():Cfg::playedBadColor(), + (!m_followPlayingTimeOut)? Cfg::colorTheme().playedGoodColor : Cfg::colorTheme().playedBadColor, m_chordDeltaTime, pianistTiming); if (validatePianistChord() == true) @@ -747,7 +747,7 @@ void CConductor::pianistInput(CMidiEvent inputNote) if (hasNote) m_scoreWin->setPlayedNoteColor(inputNote.note(), - (!m_followPlayingTimeOut)? Cfg::noteColor():Cfg::playedStoppedColor(), + (!m_followPlayingTimeOut)? Cfg::colorTheme().noteColor:Cfg::colorTheme().playedStoppedColor, m_chordDeltaTime); outputSavedNotesOff(); @@ -852,7 +852,7 @@ void CConductor::followPlaying() { if (m_chordDeltaTime > m_cfg_playZoneLate ) { - missedNotesColor(Cfg::playedStoppedColor()); + missedNotesColor(Cfg::colorTheme().playedStoppedColor); fetchNextChord(); m_rating.lateNotes(m_wantedChord.length() - m_goodPlayedNotes.length()); setEventBits( EVENT_BITS_forceRatingRedraw); @@ -932,7 +932,7 @@ void CConductor::realTimeEngine(qint64 mSecTicks) m_rating.lateNotes(m_wantedChord.length() - m_goodPlayedNotes.length()); setEventBits( EVENT_BITS_forceRatingRedraw); - missedNotesColor(Cfg::playedStoppedColor()); + missedNotesColor(Cfg::colorTheme().playedStoppedColor); findImminentNotesOff(); // Don't keep any saved notes off if there are no notes down if (m_piano->pianistAllNotesDown() == 0) diff --git a/src/Draw.cpp b/src/Draw.cpp index d838975d..b6499d7f 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -93,9 +93,9 @@ void CDraw::drawStaveExtentsion(CSymbol symbol, float x, int noteWidth, bool pl whichPart_t hand = symbol.getStavePos().getHand(); if (playable) - drColor(Cfg::staveColor()); + drColor(Cfg::colorTheme().staveColor); else - drColor(Cfg::staveColorDim()); + drColor(Cfg::colorTheme().staveColorDim); glLineWidth (Cfg::staveThickness()); glBegin(GL_LINES); @@ -135,7 +135,7 @@ void CDraw::drawNoteName(int midiNote, float x, float y, int type) staveLookup_t item = CStavePos::midiNote2Name(midiNote); - drColor(Cfg::noteNameColor()); + drColor(Cfg::colorTheme().noteNameColor); glLineWidth (1.0); @@ -365,7 +365,7 @@ void CDraw::checkAccidental(CSymbol symbol, float x, float y) if (accidental != 0) { - //drColor (Cfg::lineColor()); + //drColor (Cfg::colorTheme().lineColor); if (accidental == 1) drawSymbol(CSymbol(PB_SYMBOL_sharp, symbol.getStavePos()), x - xGap, y); else if (accidental == -1) @@ -384,7 +384,7 @@ bool CDraw::drawNote(CSymbol* symbol, float x, float y, CSlot* slot, CColor colo //ppLogTrace("PB_SYMBOL_noteHead x %f y %f", x, y); if (!CChord::isNotePlayable(symbol->getNote(), 0)) { - color = Cfg::noteColorDim(); + color = Cfg::colorTheme().noteColorDim; playable = false; } drawStaveExtentsion(*symbol, x, 16, playable); @@ -471,15 +471,16 @@ bool CDraw::drawNote(CSymbol* symbol, float x, float y, CSlot* slot, CColor colo void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) { + const auto &colorTheme = Cfg::colorTheme(); CColor color = symbol.getColor(); bool playable = true; if (m_displayHand != symbol.getHand() && m_displayHand != PB_PART_both) { - if (color == Cfg::noteColor()) - color = Cfg::noteColorDim(); - if (color == Cfg::staveColor()) - color = Cfg::staveColorDim(); + if (color == colorTheme.noteColor) + color = colorTheme.noteColorDim; + if (color == colorTheme.staveColor) + color = colorTheme.staveColorDim; playable = false; } @@ -597,7 +598,7 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) //ppLogTrace("PB_SYMBOL_noteHead x %f y %f", x, y); if (!CChord::isNotePlayable(symbol.getNote(), 0)) { - color = Cfg::noteColorDim(); + color = Cfg::colorTheme().noteColorDim; playable = false; } drawStaveExtentsion(symbol, x, 16, playable); @@ -605,7 +606,7 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) // See forum post at link below from PianoBooster forum user Kory. // http://piano-booster.2625608.n2.nabble.com/Pianobooster-port-to-arm-linux-or-Android-td7572459.html // http://piano-booster.2625608.n2.nabble.com/Pianobooster-port-to-arm-linux-or-Android-td7572459.html#a7572676 - if (m_settings->coloredNotes() && color == Cfg::noteColor()) //KORY added + if (m_settings->coloredNotes() && color == colorTheme.noteColor) //KORY added { int note = symbol.getNote() % MIDI_OCTAVE; switch (note) @@ -681,7 +682,7 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) case PB_SYMBOL_drum: if (!CChord::isNotePlayable(symbol.getNote(), 0)) - color = Cfg::noteColorDim(); + color = colorTheme.noteColorDim; drColor(color); glLineWidth (3.0f); glBegin(GL_LINES); @@ -744,16 +745,16 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) case PB_SYMBOL_barLine: x += BEAT_MARKER_OFFSET * HORIZONTAL_SPACING_FACTOR; // the beat markers where entered early so now move them correctly glLineWidth (4.0f); - drColor ((m_displayHand == PB_PART_left) ? Cfg::staveColorDim() : Cfg::staveColor()); + drColor ((m_displayHand == PB_PART_left) ? colorTheme.staveColorDim : colorTheme.staveColor); oneLine(x, CStavePos(PB_PART_right, 4).getPosYRelative(), x, CStavePos(PB_PART_right, -4).getPosYRelative()); - drColor ((m_displayHand == PB_PART_right) ? Cfg::staveColorDim() : Cfg::staveColor()); + drColor ((m_displayHand == PB_PART_right) ? colorTheme.staveColorDim : colorTheme.staveColor); oneLine(x, CStavePos(PB_PART_left, 4).getPosYRelative(), x, CStavePos(PB_PART_left, -4).getPosYRelative()); break; case PB_SYMBOL_barMarker: x += BEAT_MARKER_OFFSET * HORIZONTAL_SPACING_FACTOR; // the beat markers where entered early so now move them correctly glLineWidth (5.0f); - drColor(Cfg::barMarkerColor()); + drColor(colorTheme.barMarkerColor); oneLine(x, CStavePos(PB_PART_right, m_beatMarkerHeight).getPosYRelative(), x, CStavePos(PB_PART_left, -m_beatMarkerHeight).getPosYRelative()); glDisable (GL_LINE_STIPPLE); break; @@ -761,7 +762,7 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) case PB_SYMBOL_beatMarker: x += BEAT_MARKER_OFFSET * HORIZONTAL_SPACING_FACTOR; // the beat markers where entered early so now move them correctly glLineWidth (4.0); - drColor(Cfg::beatMarkerColor()); + drColor(colorTheme.beatMarkerColor); oneLine(x, CStavePos(PB_PART_right, m_beatMarkerHeight).getPosYRelative(), x, CStavePos(PB_PART_left, -m_beatMarkerHeight).getPosYRelative()); glDisable (GL_LINE_STIPPLE); break; @@ -772,14 +773,14 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y, CSlot* slot) float bottomY = CStavePos(PB_PART_left, -m_beatMarkerHeight).getPosY(); float early = static_cast(Cfg::playZoneEarly()) * HORIZONTAL_SPACING_FACTOR; float late = static_cast(Cfg::playZoneLate()) * HORIZONTAL_SPACING_FACTOR; - //glColor3f (0.7f, 1.0f, 0.7f); - glColor3f (0.0f, 0.0f, 0.3f); + drColor(colorTheme.playingZoneBg); glRectf(x-late, topY, x + early, bottomY); glLineWidth (2.0f); - glColor3f (0.0f, 0.0f, 0.8f); + drColor(colorTheme.playingZoneMiddle); oneLine(x, topY, x, bottomY ); glLineWidth (1.0f); - glColor3f (0.0f, 0.0f, 0.6f); + glColor3f (1.0f, 0.0f, 0.6f); + drColor(colorTheme.playingZoneBorder); oneLine(x-late, topY, x-late, bottomY ); oneLine(x+early, topY, x+early, bottomY ); } @@ -840,7 +841,8 @@ void CDraw::drawStaves(float startX, float endX) glLineWidth (Cfg::staveThickness()); /* select color for all lines */ - drColor ((m_displayHand != PB_PART_left) ? Cfg::staveColor() : Cfg::staveColorDim()); + const auto &colorTheme = Cfg::colorTheme(); + drColor ((m_displayHand != PB_PART_left) ? colorTheme.staveColor : colorTheme.staveColorDim); glBegin(GL_LINES); for (i = -4; i <= 4; i+=2 ) @@ -849,7 +851,7 @@ void CDraw::drawStaves(float startX, float endX) glVertex2f (startX, pos.getPosY()); glVertex2f (endX, pos.getPosY()); } - drColor ((m_displayHand != PB_PART_right) ? Cfg::staveColor() : Cfg::staveColorDim()); + drColor ((m_displayHand != PB_PART_right) ? colorTheme.staveColor : colorTheme.staveColorDim); for (i = -4; i <= 4; i+=2 ) { CStavePos pos = CStavePos(PB_PART_left, i); @@ -866,6 +868,7 @@ void CDraw::drawKeySignature(int key) static constexpr int flatLookUpRight[] = { 0, 3,-1, 2,-2, 1,-3}; static constexpr int flatLookUpLeft[] = {-2, 1,-3, 0,-4,-1,-5}; static constexpr float gapX = 11.0f; + const auto &colorTheme = Cfg::colorTheme(); CStavePos pos; if (key == NOT_USED) @@ -878,13 +881,13 @@ void CDraw::drawKeySignature(int key) { if (i < arraySize(sharpLookUpRight)) { - drColor ((m_displayHand != PB_PART_left) ? Cfg::noteColor() : Cfg::noteColorDim()); + drColor ((m_displayHand != PB_PART_left) ? colorTheme.noteColor : colorTheme.noteColorDim); pos = CStavePos(PB_PART_right, sharpLookUpRight[i]); drawSymbol( CSymbol(PB_SYMBOL_sharp, pos), Cfg::keySignatureX() + gapX * static_cast(i) ); } if (i < arraySize(sharpLookUpLeft)) { - drColor ((m_displayHand != PB_PART_right) ? Cfg::noteColor() : Cfg::noteColorDim()); + drColor ((m_displayHand != PB_PART_right) ? colorTheme.noteColor : colorTheme.noteColorDim); pos = CStavePos(PB_PART_left, sharpLookUpLeft[i]); drawSymbol( CSymbol(PB_SYMBOL_sharp, pos), Cfg::keySignatureX() + gapX * static_cast(i) ); } @@ -894,13 +897,13 @@ void CDraw::drawKeySignature(int key) { if (i < arraySize(flatLookUpRight)) { - drColor ((m_displayHand != PB_PART_left) ? Cfg::noteColor() : Cfg::noteColorDim()); + drColor ((m_displayHand != PB_PART_left) ? colorTheme.noteColor : colorTheme.noteColorDim); pos = CStavePos(PB_PART_right, flatLookUpRight[i]); drawSymbol( CSymbol(PB_SYMBOL_flat, pos), Cfg::keySignatureX() + gapX * static_cast(i) ); } if (i < arraySize(flatLookUpLeft)) { - drColor ((m_displayHand != PB_PART_right) ? Cfg::noteColor() : Cfg::noteColorDim()); + drColor ((m_displayHand != PB_PART_right) ? colorTheme.noteColor : colorTheme.noteColorDim); pos = CStavePos(PB_PART_left, flatLookUpLeft[i]); drawSymbol( CSymbol(PB_SYMBOL_flat, pos), Cfg::keySignatureX() + gapX * static_cast(i) ); } diff --git a/src/GlView.cpp b/src/GlView.cpp index 9613e036..649c65e7 100644 --- a/src/GlView.cpp +++ b/src/GlView.cpp @@ -54,6 +54,7 @@ CGLView::CGLView(QtWindow* parent, CSettings* settings) m_settings = settings; m_rating = nullptr; m_fullRedrawFlag = true; + m_themeChange = false; m_forcefullRedraw = 0; m_forceRatingRedraw = 0; m_forceBarRedraw = 0; @@ -96,10 +97,32 @@ void CGLView::startTimerEvent() m_allowedTimerEvent=true; } +void CGLView::reportColorThemeChange() +{ + const auto ¬eColor = Cfg::colorTheme().noteColor; + m_themeChange = true; + m_fullRedrawFlag = true; + m_score->refreshNoteColor(noteColor); + m_song->refreshScroll(); + m_score->refreshScroll(); + CDraw::forceCompileRedraw(); + repaint(); +} + void CGLView::paintGL() { BENCHMARK(2, "enter"); + if (m_themeChange) { + auto *const ctx = context(); + auto *const funcs = ctx->functions(); + const auto &colorTheme = Cfg::colorTheme(); + const auto &backgroundColor = colorTheme.backgroundColor; + funcs->glClearColor(backgroundColor.red, backgroundColor.green, backgroundColor.blue, 0.0); + funcs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_themeChange = false; + } + m_displayUpdateTicks = 0; if (m_fullRedrawFlag) @@ -153,14 +176,14 @@ void CGLView::drawTimeSignature() x = Cfg::timeSignatureX(); - CDraw::drColor ((CDraw::getDisplayHand() != PB_PART_left) ? Cfg::noteColor() : Cfg::noteColorDim()); + CDraw::drColor ((CDraw::getDisplayHand() != PB_PART_left) ? Cfg::colorTheme().noteColor : Cfg::colorTheme().noteColorDim); y = CStavePos(PB_PART_right, 0).getPosY() + 5; renderText(x,y, 0, bufferTop, m_timeSigFont); y = CStavePos(PB_PART_right, -3).getPosY() - 2; renderText(x,y, 0, bufferBottom, m_timeSigFont); - CDraw::drColor ((CDraw::getDisplayHand() != PB_PART_right) ? Cfg::noteColor() : Cfg::noteColorDim()); + CDraw::drColor ((CDraw::getDisplayHand() != PB_PART_right) ? Cfg::colorTheme().noteColor : Cfg::colorTheme().noteColorDim); y = CStavePos(PB_PART_left, 0).getPosY() + 5; renderText(x,y, 0, bufferTop, m_timeSigFont); @@ -187,15 +210,16 @@ void CGLView::drawAccurracyBar() m_rating->calculateAccuracy(); + const auto &colorTheme = Cfg::colorTheme(); accuracy = m_rating->getAccuracyValue(); color = m_rating->getAccuracyColor(); CDraw::drColor (color); glRectf(x, y - lineWidth, x + width * accuracy, y + lineWidth); - CDraw::drColor (Cfg::backgroundColor()); + CDraw::drColor (colorTheme.backgroundColor); glRectf(x + width * accuracy, y - lineWidth, x + width, y + lineWidth); glLineWidth (1); - CDraw::drColor (CColor(1.0, 1.0, 1.0)); + CDraw::drColor(colorTheme.textColor); glBegin(GL_LINE_LOOP); glVertex2f (x, y + lineWidth); glVertex2f (x+ width, y + lineWidth); @@ -224,7 +248,8 @@ void CGLView::drawDisplayText() return; } - glColor3f(1.0f,1.0f,1.0f); + const auto &colorTheme = Cfg::colorTheme(); + CDraw::drColor(colorTheme.textColor); if (m_song->getPlayMode() != PB_PLAY_MODE_listen) { if (accuracyBarStart == 0) { @@ -260,10 +285,7 @@ void CGLView::drawBarNumber() const auto y = static_cast(Cfg::getAppHeight() - m_titleHeight - 34); const auto x = static_cast(TEXT_LEFT_MARGIN); - //CDraw::drColor (Cfg::backgroundColor()); - //CDraw::drColor (Cfg::noteColorDim()); - //glRectf(x+30+10, y-2, x + 80, y + 16); - glColor3f(1.0f,1.0f,1.0f); + CDraw::drColor (Cfg::colorTheme().textColor); renderText(x, y, 0, tr("Bar:") + " " + QString::number(m_song->getBarNumber()), m_timeRatingFont); } @@ -325,7 +347,7 @@ void CGLView::mouseMoveEvent(QMouseEvent *event) void CGLView::initializeGL() { - CColor color = Cfg::backgroundColor(); + CColor color = Cfg::colorTheme().backgroundColor; glClearColor (color.red, color.green, color.blue, 0.0); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glShadeModel (GL_FLAT); diff --git a/src/GlView.h b/src/GlView.h index 674d5692..620420d4 100644 --- a/src/GlView.h +++ b/src/GlView.h @@ -54,6 +54,7 @@ class CGLView : public QOpenGLWidget//, RtTimer void stopTimerEvent(); void startTimerEvent(); + void reportColorThemeChange(); protected: void timerEvent(QTimerEvent *event); @@ -89,6 +90,7 @@ class CGLView : public QOpenGLWidget//, RtTimer QFont m_timeRatingFont; // TODO remove these as no longer required bool m_fullRedrawFlag; + bool m_themeChange; int m_forcefullRedraw; int m_forceRatingRedraw; int m_forceBarRedraw; diff --git a/src/Notation.cpp b/src/Notation.cpp index df26d9b7..9bc5530d 100644 --- a/src/Notation.cpp +++ b/src/Notation.cpp @@ -282,7 +282,7 @@ void CNotation::findNoteSlots() else symbolType = PB_SYMBOL_noteHead; CSymbol symbol(symbolType, hand, midi.note()); - symbol.setColor(Cfg::noteColor()); + symbol.setColor(Cfg::colorTheme().noteColor); symbol.setMidiDuration(midi.getDuration()); // check if this note has occurred in this bar before @@ -379,3 +379,14 @@ void CNotation::reset() noteState.clear(); setupNotationParamaters(); } + +void CNotation::resetNoteColor(CColor color) +{ + m_currentSlot.setNoteColor(0, color); + for (auto i = 0, len = m_slotQueue->length(); i != len; ++i) { + m_slotQueue->indexPtr(i)->setNoteColor(0, color); + } + for (auto &slot : m_mergeSlots) { + slot.setNoteColor(0, color); + } +} diff --git a/src/Notation.h b/src/Notation.h index b7e6ed6a..3560a99b 100644 --- a/src/Notation.h +++ b/src/Notation.h @@ -185,6 +185,7 @@ class CNotation delete m_slotQueue; } void reset(); + void resetNoteColor(CColor color); void setChannel(int channel) {m_displayChannel = channel;} diff --git a/src/Piano.cpp b/src/Piano.cpp index 5241d9e8..18182f60 100644 --- a/src/Piano.cpp +++ b/src/Piano.cpp @@ -282,12 +282,13 @@ void CPiano::drawPianoInput() { bool showNoteName = m_settings->showNoteNames(); int lineLength = (showNoteName) ? PIANO_LINE_LENGTH_SHORT : PIANO_LINE_LENGTH_LONG; + const auto &colorTheme = Cfg::colorTheme(); if (m_goodChord.length() > 0) - drawPianoInputLines(&m_goodChord, Cfg::pianoGoodColor(), lineLength); + drawPianoInputLines(&m_goodChord, colorTheme.pianoGoodColor, lineLength); if (m_badChord.length() > 0) - drawPianoInputLines(&m_badChord, Cfg::pianoBadColor(), lineLength); + drawPianoInputLines(&m_badChord, colorTheme.pianoBadColor, lineLength); if (showNoteName) drawPianoInputNoteNames(); diff --git a/src/QtWindow.cpp b/src/QtWindow.cpp index ae4800d5..4cef9f88 100644 --- a/src/QtWindow.cpp +++ b/src/QtWindow.cpp @@ -422,11 +422,28 @@ void QtWindow::createMenus() m_fileMenu->addAction(m_exitAct); updateRecentFileActions(); + m_colorThemeMenu = new QMenu(tr("Color theme"), this); + m_colorThemeActGrp = new QActionGroup(this); + m_colorThemeActGrp->setExclusive(true); + m_colorThemeMenu->addAction(tr("Default"))->setActionGroup(m_colorThemeActGrp); + m_colorThemeMenu->addAction(tr("Light"))->setActionGroup(m_colorThemeActGrp); + const auto &actions = m_colorThemeActGrp->actions(); + for (auto *const action : actions) { + action->setCheckable(true); + } + connect(m_colorThemeActGrp, &QActionGroup::triggered, this, &QtWindow::changeColorTheme); + const auto configuredThemeIndex = m_settings->value("View/BuiltInThemeIndex").toInt(); + auto *const configuredThemeAction = actions[configuredThemeIndex >= actions.size() ? 0 : configuredThemeIndex]; + configuredThemeAction->setChecked(true); + Cfg::loadColorTheme(static_cast(configuredThemeIndex)); + m_glWidget->reportColorThemeChange(); + m_viewMenu = menuBar()->addMenu(tr("&View")); m_viewMenu->setToolTipsVisible(true); m_viewMenu->addAction(m_sidePanelStateAct); m_viewMenu->addAction(m_fullScreenStateAct); m_viewMenu->addAction(m_viewPianoKeyboard); + m_viewMenu->addMenu(m_colorThemeMenu); m_songMenu = menuBar()->addMenu(tr("&Song")); m_songMenu->setToolTipsVisible(true); @@ -463,6 +480,14 @@ void QtWindow::openRecentFile() m_settings->openSongFile(action->data().toString()); } +void QtWindow::changeColorTheme(QAction *triggeredAction) +{ + const auto builtInThemeIndex = m_colorThemeActGrp->actions().indexOf(triggeredAction); + Cfg::loadColorTheme(static_cast(builtInThemeIndex)); + m_settings->setValue("View/BuiltInThemeIndex", builtInThemeIndex); + m_glWidget->reportColorThemeChange(); +} + void QtWindow::showMidiSetup(){ m_topBar->stopMuiscPlaying(); diff --git a/src/QtWindow.h b/src/QtWindow.h index 238ebfa6..968840ee 100644 --- a/src/QtWindow.h +++ b/src/QtWindow.h @@ -84,6 +84,7 @@ private slots: void about(); void keyboardShortcuts(); void openRecentFile(); + void changeColorTheme(QAction *triggeredAction); void showMidiSetup(); @@ -220,6 +221,7 @@ private slots: QMenu *m_fileMenu; QMenu *m_viewMenu; + QMenu *m_colorThemeMenu; QMenu *m_songMenu; QMenu *m_setupMenu; QMenu *m_helpMenu; @@ -229,6 +231,7 @@ private slots: QAction *m_separatorAct; QAction *m_recentFileActs[maxRecentFiles()]; + QActionGroup *m_colorThemeActGrp; }; #endif // __QT_WINDOW_H__ diff --git a/src/Score.cpp b/src/Score.cpp index 66b21a2c..0fcb7ce6 100644 --- a/src/Score.cpp +++ b/src/Score.cpp @@ -70,7 +70,7 @@ void CScore::drawScroll(bool refresh) { float topY = CStavePos(PB_PART_right, MAX_STAVE_INDEX).getPosY(); float bottomY = CStavePos(PB_PART_left, MIN_STAVE_INDEX).getPosY(); - drColor (Cfg::backgroundColor()); + drColor (Cfg::colorTheme().backgroundColor); glRectf(Cfg::scrollStartX(), topY, static_cast(Cfg::getAppWidth()), bottomY); } @@ -122,6 +122,23 @@ void CScore::drawPianoKeyboard(){ stopped = false; } + void drawBackground() { + const auto backgroundColor = CColor(0.0f, 0.0f, 0.0f); + const auto backgroundMargin = 2.5f; + const auto backgroundHight = ySize + 12.5f + backgroundMargin; + const auto backgroundX = Cfg::staveStartX() - backgroundMargin; + const auto backgroundRight = backgroundX + xSize + backgroundMargin; + CDraw::drColor(backgroundColor); + glPushMatrix(); + glBegin(GL_QUADS); + glVertex2f(backgroundX, backgroundHight); + glVertex2f(backgroundRight, backgroundHight); + glVertex2f(backgroundRight, 0.0f); + glVertex2f(backgroundX, 0.0f); + glEnd(); + glPopMatrix(); + } + void drawBlackKey(int i, int k) { glPushMatrix(); float yBlackShift = ySize / 2.5f; @@ -133,8 +150,8 @@ void CScore::drawPianoKeyboard(){ float xKeySize = this->xKeySize / 1.5f; CDraw::drColor (CColor(0.0, 0.0, 0.0)); - if(state[k]==1) CDraw::drColor(stopped ? Cfg::playedStoppedColor() : Cfg::noteColor()); - if(state[k]==2) CDraw::drColor(Cfg::playedBadColor()); + if(state[k]==1) CDraw::drColor(stopped ? Cfg::colorTheme().playedStoppedColor : Cfg::colorTheme().noteColor); + if(state[k]==2) CDraw::drColor(Cfg::colorTheme().playedBadColor); glBegin(GL_QUADS); glVertex2f(0, yBlackSize); glVertex2f(xKeySize, yBlackSize); @@ -152,8 +169,8 @@ void CScore::drawPianoKeyboard(){ glTranslatef(Cfg::staveStartX() + xPlaceSize * static_cast(i++), yStart, 0.0f); CDraw::drColor (CColor(1.0, 1.0, 1.0)); - if(state[k]==1) CDraw::drColor(stopped ? Cfg::playedStoppedColor() : Cfg::noteColor()); - if(state[k]==2) CDraw::drColor(Cfg::playedBadColor()); + if(state[k]==1) CDraw::drColor(stopped ? Cfg::colorTheme().playedStoppedColor : Cfg::colorTheme().noteColor); + if(state[k]==2) CDraw::drColor(Cfg::colorTheme().playedBadColor); glBegin(GL_QUADS); glVertex2f(0, ySize); glVertex2f(xKeySize, ySize); @@ -186,6 +203,7 @@ void CScore::drawPianoKeyboard(){ } void drawKeyboard() { + drawBackground(); i = k = 0; drawWhiteKey(); int b1 = i, k1 = k++; @@ -228,7 +246,7 @@ void CScore::drawScore() m_scoreDisplayListId = glGenLists (1); glNewList (m_scoreDisplayListId, GL_COMPILE_AND_EXECUTE); - drColor (Cfg::staveColor()); + drColor (Cfg::colorTheme().staveColor); drawSymbol(CSymbol(PB_SYMBOL_gClef, CStavePos(PB_PART_right, -1)), Cfg::clefX()); // The Treble Clef drawSymbol(CSymbol(PB_SYMBOL_fClef, CStavePos(PB_PART_left, 1)), Cfg::clefX()); diff --git a/src/Score.h b/src/Score.h index e7e3c257..0c5d6b46 100644 --- a/src/Score.h +++ b/src/Score.h @@ -102,6 +102,12 @@ class CScore : public CDraw m_scroll[m_activeScroll]->setPlayedNoteColor(note, color, wantedDelta, pianistTimming); } + void refreshNoteColor(CColor color) + { + for (auto *const scroll : m_scroll) + scroll->refreshNoteColor(color); + } + void setActiveChannel(int channel) { int newActiveSroll; diff --git a/src/Scroll.cpp b/src/Scroll.cpp index ecf0ee5c..8f0cbd4a 100644 --- a/src/Scroll.cpp +++ b/src/Scroll.cpp @@ -207,7 +207,7 @@ bool CScroll::validPianistChord(int index) int CScroll::findWantedChord(int note, CColor color, qint64 wantedDelta) { Q_UNUSED(note) - if (color == Cfg::playedBadColor()) // fixme should be an enum + if (color == Cfg::colorTheme().playedBadColor) // fixme should be an enum return m_wantedIndex; { while ( m_wantedIndex + 1 < m_scrollQueue->length()) @@ -251,9 +251,19 @@ void CScroll::refresh() compileSlot(m_scrollQueue->index(i)); } +void CScroll::refreshNoteColor(CColor color) +{ + m_notation->resetNoteColor(color); + m_headSlot.setNoteColor(0, color); + for (auto i = 0, len = m_scrollQueue->length(); i != len; ++i) { + m_scrollQueue->indexPtr(i)->setNoteColor(0, color); + } +} + bool CScroll::getKeyboardInfo(int *notes) { int stoppedScrollIdx = -1; + const auto &colorTheme = Cfg::colorTheme(); for(int i=0; ilength(); ++i) { CSlotDisplayList &info = *m_scrollQueue->indexPtr(i); if(m_show == false || info.m_displayListId == 0) continue; @@ -261,7 +271,7 @@ bool CScroll::getKeyboardInfo(int *notes) CSlot* slot = &info; for(int j=0; jlength(); ++j) { if(slot->getSymbol(j).getType() < PB_SYMBOL_noteHead) continue; - if(slot->getSymbol(j).getColor() == Cfg::playedStoppedColor()) { + if(slot->getSymbol(j).getColor() == colorTheme.playedStoppedColor) { stoppedScrollIdx = i; break; } @@ -276,7 +286,7 @@ bool CScroll::getKeyboardInfo(int *notes) CSlot* slot = &info; for(int j=0; jlength(); ++j) { if(slot->getSymbol(j).getType() < PB_SYMBOL_noteHead) continue; - slot->getSymbolPtr(j)->setColor(Cfg::playedGoodColor()); + slot->getSymbolPtr(j)->setColor(colorTheme.playedGoodColor); } } } @@ -291,10 +301,10 @@ bool CScroll::getKeyboardInfo(int *notes) for(int j=0; jlength(); ++j) { if(slot->getSymbol(j).getType() < PB_SYMBOL_noteHead) continue; - if(slot->getSymbol(j).getColor() == Cfg::noteColor() || - slot->getSymbol(j).getColor() == Cfg::playedStoppedColor()) + if(slot->getSymbol(j).getColor() == colorTheme.noteColor || + slot->getSymbol(j).getColor() == colorTheme.playedStoppedColor) *(note++) = slot->getSymbol(j).getNote(); - if(slot->getSymbol(j).getColor() == Cfg::playedStoppedColor()) stopped = true; + if(slot->getSymbol(j).getColor() == colorTheme.playedStoppedColor) stopped = true; } if(note != notes) return stopped; } diff --git a/src/Scroll.h b/src/Scroll.h index 292070d2..8cbb3539 100644 --- a/src/Scroll.h +++ b/src/Scroll.h @@ -63,6 +63,7 @@ class CScroll : public CDraw void scrollDeltaTime(qint64 ticks); void transpose(int transpose); void refresh(); + void refreshNoteColor(CColor color); void setPlayedNoteColor(int note, CColor color, qint64 wantedDelta, qint64 pianistTimming); void setChannel(int chan) { diff --git a/src/Symbol.h b/src/Symbol.h index ec5beb82..7405dd04 100644 --- a/src/Symbol.h +++ b/src/Symbol.h @@ -88,7 +88,7 @@ class CSymbol init(); } - CSymbol(musicalSymbol_t type, CStavePos stavePos, CColor color = Cfg::noteColor()) + CSymbol(musicalSymbol_t type, CStavePos stavePos, CColor color = Cfg::colorTheme().noteColor) { init(); m_symbolType = type;