diff --git a/ftl/core/preferences.ftl b/ftl/core/preferences.ftl index 23b72f267..aa09cb2ce 100644 --- a/ftl/core/preferences.ftl +++ b/ftl/core/preferences.ftl @@ -22,6 +22,7 @@ preferences-scheduling = Scheduling preferences-show-learning-cards-with-larger-steps = Show learning cards with larger steps before reviews preferences-show-next-review-time-above-answer = Show next review time above answer buttons preferences-spacebar-rates-card = Spacebar (or enter) also answers card +preferences-show-colored-buttons = Show colored border on answer buttons preferences-show-play-buttons-on-cards-with = Show play buttons on cards with audio preferences-show-remaining-card-count = Show remaining card count preferences-some-settings-will-take-effect-after = Some settings will take effect after you restart Anki. diff --git a/proto/anki/config.proto b/proto/anki/config.proto index ea115f0fc..40371e78d 100644 --- a/proto/anki/config.proto +++ b/proto/anki/config.proto @@ -57,6 +57,7 @@ message ConfigKey { LOAD_BALANCER_ENABLED = 26; FSRS_SHORT_TERM_WITH_STEPS_ENABLED = 27; FSRS_LEGACY_EVALUATE = 28; + SHOW_COLORED_BUTTONS = 29; } enum String { SET_DUE_BROWSER = 0; @@ -120,6 +121,7 @@ message Preferences { uint32 time_limit_secs = 5; bool load_balancer_enabled = 6; bool fsrs_short_term_with_steps_enabled = 7; + bool show_colored_buttons = 8; } message Editing { bool adding_defaults_to_current_deck = 1; diff --git a/qt/aqt/data/web/css/reviewer-bottom.scss b/qt/aqt/data/web/css/reviewer-bottom.scss index 59098a5fb..a514474f2 100644 --- a/qt/aqt/data/web/css/reviewer-bottom.scss +++ b/qt/aqt/data/web/css/reviewer-bottom.scss @@ -30,6 +30,27 @@ button { position: relative; } +.answerButton, +.answerButton:hover { + border-style: solid; +} + +.answerButton:focus { + border-style: dashed; +} + +.answerIncorrect, +.answerIncorrect:hover, +.answerIncorrect:focus { + border-color: color(border-answerIncorrect); +} + +.answerCorrect, +.answerCorrect:hover, +.answerCorrect:focus { + border-color: color(border-answerCorrect); +} + .hitem { margin-top: 2px; } diff --git a/qt/aqt/forms/preferences.ui b/qt/aqt/forms/preferences.ui index 0035e1f42..9383dafce 100644 --- a/qt/aqt/forms/preferences.ui +++ b/qt/aqt/forms/preferences.ui @@ -425,6 +425,19 @@ + + + + + 0 + 0 + + + + preferences_show_colored_buttons + + + @@ -1271,6 +1284,7 @@ interrupt_audio showProgress showEstimates + showColoredButtons spacebar_rates_card render_latex url_schemes diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py index 939dd8c2c..8a702e5d9 100644 --- a/qt/aqt/preferences.py +++ b/qt/aqt/preferences.py @@ -137,6 +137,7 @@ class Preferences(QDialog): form.showEstimates.setChecked(reviewing.show_intervals_on_buttons) form.showProgress.setChecked(reviewing.show_remaining_due_counts) form.showPlayButtons.setChecked(not reviewing.hide_audio_play_buttons) + form.showColoredButtons.setChecked(reviewing.show_colored_buttons) form.interrupt_audio.setChecked(reviewing.interrupt_audio_when_answering) editing = self.prefs.editing @@ -172,6 +173,7 @@ class Preferences(QDialog): reviewing.show_intervals_on_buttons = form.showEstimates.isChecked() reviewing.time_limit_secs = form.timeLimit.value() * 60 reviewing.hide_audio_play_buttons = not self.form.showPlayButtons.isChecked() + reviewing.show_colored_buttons = self.form.showColoredButtons.isChecked() reviewing.interrupt_audio_when_answering = self.form.interrupt_audio.isChecked() editing = self.prefs.editing diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 6d68f9e3a..de13335ef 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -919,22 +919,42 @@ timerStopped = false; extra = """id="defease" """ else: extra = "" + + if i == 1: + button_class = "answerIncorrect" + else: + button_class = "answerCorrect" + due = self._buttonTime(i, v3_labels=labels) key = ( tr.actions_shortcut_key(val=aqt.mw.pm.get_answer_key(i)) if aqt.mw.pm.get_answer_key(i) else "" ) - return """ + + if not self.mw.col.get_config_bool(Config.Bool.SHOW_COLORED_BUTTONS): + return """ """ % ( - extra, - key, - i, - i, - label, - due, - ) + extra, + key, + i, + i, + label, + due, + ) + else: + return """ +""" % ( + extra, + button_class, + key, + i, + i, + label, + due, + ) buf = "
" for ease, label in self._answerButtonList(): diff --git a/rslib/src/backend/config.rs b/rslib/src/backend/config.rs index b6e81ce2a..81edbf552 100644 --- a/rslib/src/backend/config.rs +++ b/rslib/src/backend/config.rs @@ -40,6 +40,7 @@ impl From for BoolKey { BoolKeyProto::LoadBalancerEnabled => BoolKey::LoadBalancerEnabled, BoolKeyProto::FsrsShortTermWithStepsEnabled => BoolKey::FsrsShortTermWithStepsEnabled, BoolKeyProto::FsrsLegacyEvaluate => BoolKey::FsrsLegacyEvaluate, + BoolKeyProto::ShowColoredButtons => BoolKey::ShowColoredButtons, } } } diff --git a/rslib/src/config/bool.rs b/rslib/src/config/bool.rs index c76787cb0..16121bcd9 100644 --- a/rslib/src/config/bool.rs +++ b/rslib/src/config/bool.rs @@ -54,6 +54,7 @@ pub enum BoolKey { ShowRemainingDueCountsInStudy, #[strum(to_string = "addToCur")] AddingDefaultsToCurrentDeck, + ShowColoredButtons, } /// This is a workaround for old clients that used ints to represent boolean @@ -71,6 +72,7 @@ impl Collection { // some keys default to true BoolKey::InterruptAudioWhenAnswering | BoolKey::ShowIntervalsAboveAnswerButtons + | BoolKey::ShowColoredButtons | BoolKey::AddingDefaultsToCurrentDeck | BoolKey::FutureDueShowBacklog | BoolKey::ShowRemainingDueCountsInStudy diff --git a/rslib/src/preferences.rs b/rslib/src/preferences.rs index 96be8e461..394d5bec8 100644 --- a/rslib/src/preferences.rs +++ b/rslib/src/preferences.rs @@ -97,6 +97,7 @@ impl Collection { show_remaining_due_counts: self.get_config_bool(BoolKey::ShowRemainingDueCountsInStudy), show_intervals_on_buttons: self .get_config_bool(BoolKey::ShowIntervalsAboveAnswerButtons), + show_colored_buttons: self.get_config_bool(BoolKey::ShowColoredButtons), time_limit_secs: self.get_answer_time_limit_secs(), load_balancer_enabled: self.get_config_bool(BoolKey::LoadBalancerEnabled), fsrs_short_term_with_steps_enabled: self @@ -119,6 +120,7 @@ impl Collection { BoolKey::ShowIntervalsAboveAnswerButtons, s.show_intervals_on_buttons, )?; + self.set_config_bool_inner(BoolKey::ShowColoredButtons, s.show_colored_buttons)?; self.set_answer_time_limit_secs(s.time_limit_secs)?; self.set_config_bool_inner(BoolKey::LoadBalancerEnabled, s.load_balancer_enabled)?; self.set_config_bool_inner( diff --git a/ts/lib/sass/_vars.scss b/ts/lib/sass/_vars.scss index a8da766ad..65d99c6b3 100644 --- a/ts/lib/sass/_vars.scss +++ b/ts/lib/sass/_vars.scss @@ -178,6 +178,20 @@ $vars: ( dark: palette(blue, 5), ), ), + answerCorrect: ( + "Border color of answer buttons that show the answer was correct (hard, good, easy)", + ( + light: palette(green, 5), + dark: palette(green, 5), + ) + ), + answerIncorrect: ( + "Border color of the answer button that shows that the answer was incorrect (again)", + ( + light: palette(red, 5), + dark: palette(red, 5), + ) + ), ), button: ( bg: (